Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Объявление глобального массива в C, длина которого константная переменная
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему > Программирование
Grizzzly
Удивлен, что компилятор Keil с включенным стандартом C99 не выдал ошибки для такого кода:

Код
const uint32_t N = 20;
static MyStruct_t Example[N];


В C в отличие от C++ const означает только read-only. Variable length array, появившийся в C99, применяется к локальным массивам в run-time.
Почему в моем случае нет ошибки для глобального массива? Странное поведение.
gazpar
Цитата(Grizzzly @ Nov 26 2017, 18:37) *
Удивлен, что компилятор Keil с включенным стандартом C99 не выдал ошибки для такого кода:

Код
const uint32_t N = 20;
static MyStruct_t Example[N];


В C в отличие от C++ const означает только read-only. Variable length array, появившийся в C99, применяется к локальным массивам в run-time.
Почему в моем случае нет ошибки для глобального массива? Странное поведение.

Странно, почему для вас этот код странный. Всё ок. Попробуйте изменить значение N в рантайме (в цикле N присвоить значение индекса/итерации цикла)--> будет ошибка.
Grizzzly
Цитата(gazpar @ Nov 26 2017, 19:44) *
Странно, почему для вас этот код странный. Всё ок. Попробуйте изменить значение N в рантайме (в цикле N присвоить значение индекса/итерации цикла)--> будет ошибка.

Это я понимаю, что менять нельзя значение переменной. Более того, она должна быть объявлена const, иначе будет ошибка.
Почему тогда приводятся во всех книгах/примерах определения размеров массивов через define? Я имею в виду Си.
Наверное, час искал на форумах, но нигде не нашел примеров, чтобы определяли длину через const int. Мне самому именно такой метод нравится больше по сравнению с define. Сейчас задумался, правильно ли я понимаю стандарт и не допускаю ли ошибки. В C++ это обычная практика.
k155la3
Цитата(gazpar @ Nov 26 2017, 19:44) *
. . . Попробуйте изменить значение N в рантайме (в цикле N присвоить значение индекса/итерации цикла)--> будет ошибка.
. . .
const с инициализацией размещается или во флеш, или реализуется оптимизатором как присваивание (если использование "разовое").Поэтому, если у компилятора есть совесть, до рантайма дойти не должно. Должна быть ошибка компилятора.
Цитата(Grizzzly @ Nov 26 2017, 19:51) *
. . . . Почему тогда приводятся во всех книгах/примерах определения размеров массивов через define? . . .

Это не "определение", это "тупо подстановка" текста-цифров.
Через #define - тк далее в коде это значение может еще много-где понадобиться (и измениться),
а это удобно делать "централизованно" из одного #define.
------
А для "определения" - sizeof(). И такая конструкция вроде прокатывает:
Код
int a, b; float c; char ms[100];
const int bf_size = sizeof(a) + sizeof(b) + sizeof(ms);
one_eight_seven
Неплохо бы указывать. в каком компиляторе это у вас нет ошибки.
Grizzzly
Цитата(one_eight_seven @ Nov 26 2017, 20:14) *
Неплохо бы указывать. в каком компиляторе это у вас нет ошибки.

Arm Compiler 5.02 и 5.06.
P.S. Если выбрать C90, то тоже ошибок нет.
one_eight_seven
мой gcc ругается на это сразу: "variable modified array 'MyArray' at file scopoe", если я ставлю (не структуту, просто int'овый массив), если я делаю глобальный массив int MyArray[int].
если же я включаю его в тело функции, то он сообщает, что "storage size of 'MyArray' isn't constant.

В общем-то так было всегда., сколько я ни мучаю gcc Так что либо смотрите на настройки компиляции, либо бегите от этого компилятора, как от огня. Какой бы он хороший ни был, если он не соответствует документации, то вы не можете ждать от него детерминированного результата.
Grizzzly
Цитата(one_eight_seven @ Nov 26 2017, 20:29) *

От GCC я другого не ожидал sm.gif Тут нет вопросов. Задал тоже просто массив int'ов для Arm Compiler. Такая же фигня. Для успокоения совести выбрал C99 и добавил определение массива в main(), создался VLA. Для C90 это вызвало ошибку. То есть использование стандартов Си изменяется в настройках корректно. При этом как для C90, так и для C99 в случае глобального массива ни ворнингов, ни ошибок sad.gif Может быть, кто-то еще повторит подобное. Вдруг я где-то ошибся.
ViKo
попробуйте компилировать с опцией --strict
Grizzzly
Цитата(ViKo @ Nov 26 2017, 21:24) *
попробуйте компилировать с опцией --strict

Спасибо.
Для C90 совсем всё плохо, миллион ошибок сразу. Для C99 много ошибок при компиляции CMSIS следующего вида:

Код
/core_cm3.c", line 58: Error:  #667: "asm" function is nonstandard
  __ASM uint32_t __get_PSP(void)


И еще неизвестно, сколько их будет дальше. Надо тогда попробовать сделать совсем маленький проектик.

UPD.: Задал опцию --strict только для файла main.c, сразу получил ошибку в моем массиве sm.gif

Код
Error:  #28: expression must have a constant value


А не подскажете, где-нибудь в документации Arm Compiler перечислены их фичи, отличные от стандарта?

Цитата(one_eight_seven @ Nov 26 2017, 20:29) *
В общем-то так было всегда., сколько я ни мучаю gcc Так что либо смотрите на настройки компиляции, либо бегите от этого компилятора, как от огня. Какой бы он хороший ни был, если он не соответствует документации, то вы не можете ждать от него детерминированного результата.

А вы с опциями --pedantic или --ansi компилируете? Хочу понять, в GCC изначально более жесткое соблюдение стандарта или нет...
ViKo
ARM Compiler armcc user guide. Есть на сайте ARM и Keil. Где что перечислено, не знаю. Я его только местами смотрел. Про --strict там конкретно написано, на что реагирует. Я его так и нашел по слову const.
Grizzzly
Цитата(ViKo @ Nov 26 2017, 22:19) *
ARM Compiler armcc user guide. Есть на сайте ARM и Keil. Где что перечислено, не знаю. Я его только местами смотрел. Про --strict там конкретно написано, на что реагирует. Я его так и нашел по слову const.

Ага, пасиб. Guide этот знаю, завтра почитаю подробнее.
UPD.: Вот тут весь списочек: http://infocenter.arm.com/help/index.jsp?t...e/CHDGFDID.html
Только сходу свой случай не нашел.
one_eight_seven
Цитата
А вы с опциями --pedantic или --ansi компилируете? Хочу понять, в GCC изначально более жесткое соблюдение стандарта или нет...

Без опций.
Собственно, листинг моего Makefile:
Код
CFLAGS=-g -Wall -O0

falsenoerror: falsenoerror.o


сам код:
Код
#include <stdio.h>
#include <stdint.h>

const uint32_t N = 20;


int main () {
    static int MyArray[N];

    for (int i=0 i < N; i++) {
        MyArray[i] = i;
        print ("MyArray %d = %d", i, MyArray[i])
    }
    return 0;
}


Естественно, если вынести строку
Код
static int MyArray[N];

из тела main, ничего не изменится.
Grizzzly
Цитата(one_eight_seven @ Nov 26 2017, 23:11) *

Спасибо большое. Опередили. Отыскал свои проекты под GCC, но вы раньше показали пример.
Читаю описания Arm Compiler, немало всяких дополнений там, отличных от стандарта.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.