элемент инициализатора не постоянный?

Я относительно хорошо знаком с C и только изучаю его, чтобы опубликовать приложение Pebble C / PebbleKitJS для отслеживания автобусов. Пока у меня есть данные, обрабатываемые на сервере Node, и я готовлюсь к обработке данных с помощью файла JS. Моя одна проблема, однако, заключается в коде C.

Этот код обрабатывает данные, хранящиеся в Key Dictionary, отправленном из JS, и назначает их переменной для использования ниже. Используя #define var 9, я могу успешно установить для .high значение 9. Но через int var он терпит неудачу и выдает ошибку: элемент инициализатора не постоянный ?? .

Что означает эта ошибка и какова разница между статическим и постоянным, если я не определяю его. по-видимому, статические вары ничего не возвращают? Некоторая помощь будет очень признательна.

ОБНОВЛЕНИЕ: проблема все еще не устранена. Следующее новое сообщение об ошибке появляется в дополнение к сообщению инициализатора. error: (near initialization for 's_data_points[0].high')

   int key0_buffer; 


  void process_tuple(Tuple *t)
{
    //Get key
    int key = t->key;

    //Get integer value, if present
     int value = t->value->int32;

    //Get string value, if present
    char string_value[32];
    strcpy(string_value, t->value->cstring);

    //Decide what to do
    switch(key) {
        case key_0:
            //Location received
            key0_buffer = value;
            break;
  }



  }

static WeatherAppDataPoint s_data_points[] = {

  {
 .city = "San Diego",
     .description = "surfboard :)",
        .icon = WEATHER_APP_ICON_GENERIC_WEATHER,
        .current = 110,
        .high = key0_buffer,
        .low = 9,
  },   
};

person AgentSpyname    schedule 11.05.2015    source источник


Ответы (2)


Попробуйте вместо этого:

enum { key0_buffer = 9 };
  • C не предусматривает вычислений во время выполнения при инициализации глобальных переменных. (Эта концепция существует как функция C ++, называемая «динамической инициализацией».)

    Модель выполнения состоит в том, что она может хранить все байты глобальных переменных в ПЗУ, а затем копировать любые изменяемые переменные в ОЗУ вместе с одним memcpy. Назначить один глобал другому было бы сложнее.

  • #define позволяет заменить текст 9, который является постоянным выражением.

    Многие не одобряют использование текстовых замен, чтобы избежать переменных как примитивных, излишне низкоуровневых и потенциально неэффективных. Однако в этом случае результаты должны быть такими же.

  • В C константы enum имеют тип int, поэтому они могут быть подходящей заменой. А вот с другими типами тебе не повезло.

person Potatoswatter    schedule 11.05.2015
comment
Если s_data_points был локальным, был бы разрешен инициализатор? (Давно не использовал C ...) - person Jesse Good; 11.05.2015
comment
@JesseGood Это немного не по теме. Я помню, что это запрещено в C89, но я не уверен, разрешено ли это в современных редакциях. Вопрос уже использует некоторые возможности C99. - Ах, сейчас проверил C11, и он говорит, что все выражения в инициализаторе для объекта, который имеет статическую продолжительность или продолжительность хранения потока, должны быть константными выражениями или строковыми литералами, поэтому я думаю, что сейчас это разрешено. - person Potatoswatter; 11.05.2015
comment
Ах да, designated initializers это функция C99. Я нашел ответ In C90, the initialization of array is invalid, since function calls are not constant expressions. C99 removes this restriction for objects with automatic storage duration and allows any run-time expression to be used in the brace-enclosed initializer for such an object. Objects with static storage duration, regardless of type, still must be initialized with constant expressions in C99. справкой. Так что да, если бы это было местное, это было бы разрешено. - person Jesse Good; 11.05.2015
comment
@Potatoswatter Спасибо за вашу помощь. Исходя из Ruby on Rails, Python и Javascript, концепции C, такие как const и static, для меня в новинку. Принятый - person AgentSpyname; 11.05.2015
comment
Что забавно, я был близок к тому, чтобы исправить это сам, но я перепутал int const с const int. - person AgentSpyname; 11.05.2015
comment
@AgentSpyname Порядок const и int не имеет значения. - person Potatoswatter; 11.05.2015
comment
@Potatoswatter проблема все еще сохраняется .... даже с определением int const - person AgentSpyname; 11.05.2015
comment
@AgentSpyname Очень странно ... Clang принимает это, а GCC - нет. - person Potatoswatter; 11.05.2015
comment
@Potatoswatter Я использую Cloud IDE под названием CloudPebble для компиляции этого приложения ... Это только для Pebble watchapps. Я не уверен, какой компилятор он использует. - person AgentSpyname; 11.05.2015
comment
@AgentSpyname Почти наверняка это GCC. Я спросил: http://stackoverflow.com/questions/30158413/gcc-doesnt-support-simple-integer-constant-expression - person Potatoswatter; 11.05.2015
comment
@AgentSpyname Обновлено. Clang принимает const, но это только расширение. Вместо этого используйте enum. - person Potatoswatter; 11.05.2015
comment
@Potatoswatter большое спасибо, я попробую - person AgentSpyname; 11.05.2015
comment
Возможно, мне придется задать еще один вопрос, но означает ли это, что я могу использовать только целые числа, а не текст? Может, мне стоит обратиться к члену команды разработчиков Pebble? - person AgentSpyname; 11.05.2015

Существует ключевое различие между кодом в вашей функции и нижним кодом, определяющим статическую переменную. Код функции является исполняемым - эти строки будут запускаться при вызове функции.

Ваше статическое объявление WeatherAppDataPoint просто говорит компилятору создать статическую переменную. Значения инициализации, которые вы помещаете в это объявление, сообщают компилятору, каким значением инициализировать эти данные. Вот почему они должны быть постоянными - это значения, которые загружаются до того, как что-либо будет выполнено.

Оператор #define просто указывает препроцессору заменить все экземпляры «var» строкой «9». Это буквально то же самое, что и операция вырезания и вставки в текстовом редакторе. Это делается до того, как компилятор увидит код. Вот почему у вас с этим нет проблем; компилятор видит буквальную константу, как если бы вы вручную ввели "9" прямо в исходный код.

В 'C' переменные не возвращают вещи, они их хранят. Только функции возвращают вещи. Если вы хотите, чтобы где-то было объявлено целое число, а затем присвоить его значению вашей статической переменной, это фактическая исполняемая строка кода, которая должна быть где-то внутри функции (то есть внутри вашей функции process_tuple). Строки кода под статическим объявлением не выполняются во время выполнения, они просто устанавливают начальное состояние программы и сообщают компилятору, насколько велика переменная.

person Barry Gackle    schedule 11.05.2015