Форум программистов, компьютерный форум, киберфорум
C для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.81/68: Рейтинг темы: голосов - 68, средняя оценка - 4.81
213 / 202 / 85
Регистрация: 09.05.2012
Сообщений: 494
1

Ошибка компиляции "initializer element is not constant"

23.09.2013, 18:40. Показов 13768. Ответов 36
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Здравствуйте. Наткнулся(ладно, каюсь - сам написал) на вот такой код:
C
1
2
3
4
5
6
7
8
9
#include <stdio.h>
 
static const int x = 23;
static const double y = 1.0 / (double)x;
 
int main() {
    printf("x = %d, y = %lf\n", x, y);
    return 0;
}
он не компилируется в связи с тем что:
Bash
1
2
3
4
gcc -O0 -g3 -Wall -c -fmessage-length=0 -o test.o ..\test.c
..\test.c:4:1: error: initializer element is not constant
 const double y = 1.0 / (double)x;
 ^
я несколько непонимаю почему так? ведь x - константа, а 1.0 разделить на константу - тоже константа. то есть, я какбы константу инициализирую константой, однако gcc имеет инное мнение по этому поводу. полагаю дело в static, т.к. если убрать спецификатор const, то ошибка остается. а вот так работает:
C
1
2
3
4
5
6
7
8
9
#include <stdio.h>
 
int main() {
    const int x = 23;
    const double y = 1.0 / (double)x;
 
    printf("x = %d, y = %lf\n", x, y);
    return 0;
}
гугление выдает только информацию, касательно того как static, действует на область видимости переменной.
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
23.09.2013, 18:40
Ответы с готовыми решениями:

Initializer element is not constant
typedef struct { int (*func)(int); //Указатель на функцию char text; } menuElement; typedef...

Ошибка компиляции "assigning to an array from an initializer list"
Выбивает ошибку:|error: assigning to an array from an initializer list| #include &lt;iostream&gt;...

Ошибка "expected ‘;’, ‘,’ or ‘)’ before numeric constant" при компиляции кода
Здравствуйте! Просьба помочь разобраться с ошибкой. Изучаю Си по книге Б. Кернигана и Д. Ритчи...

Ошибка при компиляции invalid suffix "i64" on integer constant
Подскажите, при компиляции вылетает ошибка ./pluginterfaces/base/ftypes.h:82:33: error: invalid...

Ошибка: Specified element is already the logical child of another element. Disconnect it first.
В отдельной сборке я определяю ResourceDictionary с стилем для Content кнопки : ...

36
Эксперт С++
4985 / 3092 / 456
Регистрация: 10.11.2010
Сообщений: 11,169
Записей в блоге: 10
24.09.2013, 12:43 21
Author24 — интернет-сервис помощи студентам
Цитата Сообщение от fanatdebian Посмотреть сообщение
Прямых нет, косвенные есть.
Да нет там никаких косвенных макроопределений, вы где такие термины берете?
0
1259 / 650 / 44
Регистрация: 06.02.2011
Сообщений: 1,654
24.09.2013, 12:56 22
Цитата Сообщение от Evg Посмотреть сообщение
В языке Си в качестве инициализатора может быть только константное выражение
Есть одна оговорка int a = 1 ? 123 : (foo() + x) / y;
Цитата Сообщение от Evg Посмотреть сообщение
ничего под это не попадает
Немного похоже на формальные требования к обработчикам прерываний (запрет на изменение любых статических данных за исключением sig_atomic_t в том числе и по озвученным Вами причинам).
0
Evg
Эксперт CАвтор FAQ
21279 / 8301 / 637
Регистрация: 30.03.2009
Сообщений: 22,659
Записей в блоге: 30
24.09.2013, 13:01 23
Цитата Сообщение от g_u_e_s_t Посмотреть сообщение
Есть одна оговорка int a = 1 ? 123 : (foo() + x) / y;
Ни в C89, ни в C99 так нельзя писать. Можно в GNU C, но его считать за стандарт нельзя. От версии к версии у них политика партии постоянно меняется

Добавлено через 1 минуту
Цитата Сообщение от g_u_e_s_t Посмотреть сообщение
Немного похоже на формальные требования к обработчикам прерываний
Нет, что-то в голове вертится именно про разницу между статическим и динамическим инициализаторами (вызовут прерывание или не вызовут). Прерывания являются частью стандартов плавающих чисел
0
1259 / 650 / 44
Регистрация: 06.02.2011
Сообщений: 1,654
24.09.2013, 13:11 24
Цитата Сообщение от Evg Посмотреть сообщение
Ни в C89, ни в C99 так нельзя писать
Про 89 не помню, если честно. А вот 99 явным образом это разрешает

Добавлено через 5 минут
Не поленюсь кусочек привести:
Constant expressions shall not contain assignment, increment, decrement, function-call,
or comma operators, except when they are contained within a subexpression that is not
evaluated.
2
833 / 641 / 101
Регистрация: 20.08.2013
Сообщений: 2,524
24.09.2013, 13:56 25
Цитата Сообщение от Evg Посмотреть сообщение
Правда в printf'е нужно использовать %f, а не %lf, но это мелочи.
"%f" - float, "%lf" - double.
0
Evg
Эксперт CАвтор FAQ
21279 / 8301 / 637
Регистрация: 30.03.2009
Сообщений: 22,659
Записей в блоге: 30
24.09.2013, 14:05 26
Цитата Сообщение от g_u_e_s_t Посмотреть сообщение
А вот 99 явным образом это разрешает
Хм... тот компилятор, которым пользуемся мы, такое запрещает. gcc разрешает. Пойду-ка поищу icc, где-то он у нас был

Добавлено через 7 минут
Цитата Сообщение от Qwertiy Посмотреть сообщение
"%f" - float, "%lf" - double.
"%lf" в стандарте нету: http://www.cplusplus.com/reference/cstdio/printf/
Хотя gcc его жрёт и не ругается (а он умеет ругаться по опции -Wformat на неправильные аргументы printf'а). В glibc'шном man'е по printf'у ничего не нашёл про %lf.

По-моему, %f=float и %lf=double - это от scanf'а. И, видимо, для симметрии %lf перетащили в printf

float в printf невозможно передать, т.к. он в момент передачи превращается в double (по правилам promotion'а в языке Си).

Добавлено через 41 секунду
При смене Float на double программа выдает нули
0
833 / 641 / 101
Регистрация: 20.08.2013
Сообщений: 2,524
24.09.2013, 16:31 27
Цитата Сообщение от Evg Посмотреть сообщение
"%lf" в стандарте нету: http://www.cplusplus.com/reference/cstdio/printf/
Ссылочку на описание для Си, а не Си++ можно?

Добавлено через 33 секунды
Цитата Сообщение от Evg Посмотреть сообщение
float в printf невозможно передать, т.к. он в момент передачи превращается в double (по правилам promotion'а в языке Си).
Я знаю.
0
Эксперт С++
4985 / 3092 / 456
Регистрация: 10.11.2010
Сообщений: 11,169
Записей в блоге: 10
24.09.2013, 16:35 28
Цитата Сообщение от Qwertiy Посмотреть сообщение
Ссылочку на описание для Си, а не Си++ можно?
...
Compatibility
Particular library implementations may support additional specifiers and sub-specifiers.
Those listed here are supported by the latest C and C++ standards (both published in 2011), but those in yellow were introduced in C99 (only required for C++ implementations since C++11), and may not be supported by libraries that comply with older standards.
0
Evg
Эксперт CАвтор FAQ
21279 / 8301 / 637
Регистрация: 30.03.2009
Сообщений: 22,659
Записей в блоге: 30
24.09.2013, 16:40 29
Цитата Сообщение от Qwertiy Посмотреть сообщение
Ссылочку на описание для Си, а не Си++ можно?
Всё, что в Си++ начинается из инклюдов на букву c (в данном случае cstdio) - это утащено из стандарта Си. Есть ли в подобном виде где-то в инете - не знаю. В стандарте - ISO/IEC 9899:1999 раздел "7.19.6.1 The fprintf function" пункт 7. Там написано то же самое, что и по ссылке

Добавлено через 2 минуты
Цитата Сообщение от Evg Посмотреть сообщение
Пойду-ка поищу icc, где-то он у нас был
Тоже запрещает. Если я правильно понимаю написанное в стандарте, то это косяк компилятора. Попробуем написать в edg (авторы фронтенда, который используется в icc)

Код
$ icc -v
Version 8.0

$ icc t.c -std=c99
t.c(4): error: function call is not allowed in a constant expression
  int a = 1 ? 123 : (foo() + x) / y;
                     ^

t.c(4): error: expression must have a constant value
  int a = 1 ? 123 : (foo() + x) / y;
                             ^

t.c(4): error: expression must have a constant value
  int a = 1 ? 123 : (foo() + x) / y;
                                  ^
1
1259 / 650 / 44
Регистрация: 06.02.2011
Сообщений: 1,654
24.09.2013, 16:51 30
Цитата Сообщение от Evg Посмотреть сообщение
Тоже запрещает. Если я правильно понимаю написанное в стандарте, то это косяк компилятора. Попробуем написать в edg (авторы фронтенда, который используется в icc)
Вопрос целесообразности. ИМХО никто в здравом уме и памяти так не пишет. Покрайней мере я в реальном коде не встречал не разу. А с другой стороны, раз можно, то почему бы и нет

PS: добрался до компилятора, gcc и clang кушают.
0
Evg
Эксперт CАвтор FAQ
21279 / 8301 / 637
Регистрация: 30.03.2009
Сообщений: 22,659
Записей в блоге: 30
24.09.2013, 16:56 31
Ну если в стандарте есть, значит компилятор должен такое понимать. В любом случае авторы, думается, заинтересованы в том, чтобы их фронтенд строго соответствовал стандарту.

На gcc в таких вопросах я очень не люблю смотреть, потому что у них в принципе нету "чистой" поддержки какого-нибудь языка, везде просачиваются их собственные расширения, а потому дальше начинается гадание, мы имеем дело с фичей языка или с особенностью gcc. С clang'ом не работал, так что не знаю. Эталоном стандартов для меня всегда был Sun'овский компилятор, но чего-то мы тут толпой не сообразили, как его на C99 настроить
0
1259 / 650 / 44
Регистрация: 06.02.2011
Сообщений: 1,654
24.09.2013, 17:03 32
Цитата Сообщение от Evg Посмотреть сообщение
но чего-то мы тут толпой не сообразили, как его на C99 настроить
если правильно помню, то -xc99
0
Evg
Эксперт CАвтор FAQ
21279 / 8301 / 637
Регистрация: 30.03.2009
Сообщений: 22,659
Записей в блоге: 30
24.09.2013, 17:14 33
Цитата Сообщение от g_u_e_s_t Посмотреть сообщение
если правильно помню, то -xc99
Код
$ cc t.c -xc99
-xc99=lib is not available on SunOS 5.9
Дальше - круче. В стандарте c89 написано то же самое. Я то думал, что эта хрень есть только в c99, оказывается есть и в c89 тоже. Я на 100% был уверен, что в c89 этого точно нет. Блин, век живи, век учись

Sun'овский компилятор этот тест съел в режиме c89 (в дефолтном)

Добавлено через 1 минуту
Нашёл icc-11.1. Там уже всё в порядке
0
1259 / 650 / 44
Регистрация: 06.02.2011
Сообщений: 1,654
24.09.2013, 17:19 34
Цитата Сообщение от Evg Посмотреть сообщение
Блин, век живи, век учись
Тут скорее голову глупостями забивать Ну действительно же фича безполезная.
0
Evg
Эксперт CАвтор FAQ
21279 / 8301 / 637
Регистрация: 30.03.2009
Сообщений: 22,659
Записей в блоге: 30
24.09.2013, 17:21 35
Угу...
0
213 / 202 / 85
Регистрация: 09.05.2012
Сообщений: 494
24.09.2013, 19:19  [ТС] 36
Цитата Сообщение от Evg Посмотреть сообщение
В языке Си в качестве инициализатора может быть только константное выражение. В исходном примере в правой части использовалась переменная, а потому с точки зрения языка Си выражение не является константным (хотя в Си++ такое допустимо и будет работать)
понял. спасибо
0
Evg
Эксперт CАвтор FAQ
21279 / 8301 / 637
Регистрация: 30.03.2009
Сообщений: 22,659
Записей в блоге: 30
25.09.2013, 11:59 37
Цитата Сообщение от Evg Посмотреть сообщение
Попробуем написать в edg (авторы фронтенда, который используется в icc)
Товарищи согласились, что это их ошибка
0
25.09.2013, 11:59
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
25.09.2013, 11:59
Помогаю со студенческими работами здесь

Error: expected initializer before 'ip2str' при компиляции приложения
Всем привет. Помогите разобраться. При компиляции файла выдает ошибку files.cpp:204: error:...

Ошибка с отсутствующим initializer
Здравствуйте! Кусок кода ниже: class Number { private: double *num; public: ...

Ошибка: expected initializer before 'void'
Выдает ошибку expected initializer before 'void', помогите исправить #include &lt;iostream&gt; using...

Ошибка: expected initializer before 'int'
Подскажите, пожалуйста, я только начинаю изучать с++. в программе: #include &lt;iostream&gt; using...

Ошибка: array must be initialized with a brace-enclosed initializer
Приветствую, форумчане. Начал изучать С++ и у меня возникла проблема. Пытался прикрепить поинтер к...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
37
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru