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

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

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

Здравствуйте. Наткнулся(ладно, каюсь - сам написал) на вот такой код:
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
Ответы с готовыми решениями:

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

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;...

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

36
Эксперт С++
4974 / 3081 / 456
Регистрация: 10.11.2010
Сообщений: 11,160
Записей в блоге: 10
23.09.2013, 18:47 2
Мой GCC 4.7.3 жуёт без предупреждений и ошибок с флагом -pedantic
C++
1
2
3
4
5
6
7
8
9
#include <iostream>
 
static const int    a = 123;
static const double b = 1. / a;
 
int main()
{
    return 0;
}
0
213 / 202 / 85
Регистрация: 09.05.2012
Сообщений: 494
23.09.2013, 18:48  [ТС] 3
я конечно обошелся и без статичности, сделав #define, однако интересно узнать почему static const не срабатывает
0
Эксперт С++
4974 / 3081 / 456
Регистрация: 10.11.2010
Сообщений: 11,160
Записей в блоге: 10
23.09.2013, 18:55 4
Тьфу блин... это ж Си..
0
213 / 202 / 85
Регистрация: 09.05.2012
Сообщений: 494
23.09.2013, 18:56  [ТС] 5
результат на лицо консоль:
0
Миниатюры
Ошибка компиляции "initializer element is not constant"  
Z3JheSBoYXQ=
339 / 234 / 83
Регистрация: 08.07.2012
Сообщений: 577
23.09.2013, 20:42 6
Потому что static дает указание компилятору резервировать сегмент памяти в течении процесса выполнения программы под переменную. Мкроподстановки к таковым не относятся.
1
213 / 202 / 85
Регистрация: 09.05.2012
Сообщений: 494
23.09.2013, 20:46  [ТС] 7
fanatdebian, не совсем понятно. ининциализация static-переменных происходит на этапе выполнения, я правильно понял?
0
Z3JheSBoYXQ=
339 / 234 / 83
Регистрация: 08.07.2012
Сообщений: 577
23.09.2013, 20:49 8
Цитата Сообщение от lowercase Посмотреть сообщение
fanatdebian, таким образом инициализация static переменных происходит на этапе выполнения, я правильно понял?
ofc.
1
213 / 202 / 85
Регистрация: 09.05.2012
Сообщений: 494
23.09.2013, 20:53  [ТС] 9
чудненько. спасибо
0
Эксперт С++
4974 / 3081 / 456
Регистрация: 10.11.2010
Сообщений: 11,160
Записей в блоге: 10
23.09.2013, 20:56 10
Да ну при чем тут static .. это всего-лишь издержки стандарта языка Си.
0
Z3JheSBoYXQ=
339 / 234 / 83
Регистрация: 08.07.2012
Сообщений: 577
24.09.2013, 00:31 11
Цитата Сообщение от castaway Посмотреть сообщение
Да ну при чем тут static .. это всего-лишь издержки стандарта языка Си.
В чем издержки?. Все логично и правильно на самом деле. С какой стати компилятор должен для макроподстановок резервировать память. Это всего лишь конструкция-форма, определяющая короткую запись для обработки конкретных данных размещенных в памяти.
0
Эксперт С++
4974 / 3081 / 456
Регистрация: 10.11.2010
Сообщений: 11,160
Записей в блоге: 10
24.09.2013, 00:36 12
Цитата Сообщение от fanatdebian Посмотреть сообщение
С какой стати компилятор должен для макроподстановок резервировать память.
Тут же нет макроопределений. Ты о чем?
0
Z3JheSBoYXQ=
339 / 234 / 83
Регистрация: 08.07.2012
Сообщений: 577
24.09.2013, 08:59 13
Цитата Сообщение от castaway Посмотреть сообщение
Тут же нет макроопределений. Ты о чем?
Прямых нет, косвенные есть.
C
1
static const double y = 1.0 / (double)x;
Такая конструкция у компилятора вызывает диссонанс по причине отсутствия в момент прохода выделенной памяти под y для завершения остаточной конструкции / (double)x;

Не может лошадь везти телегу задом наперед.
0
Модератор
Эксперт С++
11113 / 9155 / 5502
Регистрация: 18.12.2011
Сообщений: 24,460
24.09.2013, 09:00 14
Некоторые рассуждения.
1. Глобальные переменные по определению имеют свойство static.
2. Константа, она и в Африке константа. Не могу придумать, как на нее может влиять static.
0
1259 / 650 / 44
Регистрация: 06.02.2011
Сообщений: 1,654
24.09.2013, 10:20 15
Константы (вещественные/целые числа и символы) и квалификатор типа (const/restrict/...) суть разные вещи.
0
Evg
Эксперт CАвтор FAQ
21204 / 8220 / 633
Регистрация: 30.03.2009
Сообщений: 22,538
Записей в блоге: 30
24.09.2013, 10:26 16
Цитата Сообщение от lowercase Посмотреть сообщение
я несколько непонимаю почему так?
Проблема в том, что в правой части присваивания находится выражение плавающего типа. Любое плавающее выражение обладает побочными эффектами в виде изменения состояния плавающих статусных регистров процессора, которые при определённых установленных масках должны вызывать аппаратное прерывание.

Другими словами, когда мы имеем динамическую инициализацию, то в процессе её вычисления может случиться прерывание и программа попадёт в обработчик прерываний. В случае статической инициализации такое сделать невозможно: компилятор не знает, взведены ли биты, отвечающие за прерывания, не знает, есть ли вообще обработчик прерывания. И может получиться так, что программа со статической и динамической инициализацией будет вести себя по разному. Поэтому запретили плавающие выражения в качестве статических инициализаторов
0
1259 / 650 / 44
Регистрация: 06.02.2011
Сообщений: 1,654
24.09.2013, 10:48 17
Цитата Сообщение от Evg Посмотреть сообщение
Проблема в том, что в правой части присваивания находится выражение плавающего типа
Вы о чем? как на счет int a = 1; int b = a + 1; ???
0
Z3JheSBoYXQ=
339 / 234 / 83
Регистрация: 08.07.2012
Сообщений: 577
24.09.2013, 11:24 18
Цитата Сообщение от g_u_e_s_t Посмотреть сообщение
Вы о чем? как на счет int a = 1; int b = a + 1; ???
Тут линейное присваивание. Сложностей для компилятора не видать.
Аналогично
C
1
2
int a = 1; 
int b = a + 1;
память выделена и и известны значения по этим сегментам памяти, поэтому такое присваивание и происходит без проблем.
А когда плавающая форма-конструкция как в примере у ТС, возникают казусы.
0
1259 / 650 / 44
Регистрация: 06.02.2011
Сообщений: 1,654
24.09.2013, 11:38 19
Цитата Сообщение от fanatdebian Посмотреть сообщение
Тут линейное присваивание.
Забавно. Какой-то новый стандарт языка вышел? Можно ссылку на определение термина "линейное присваивание"? Причем тут память?
Цитата Сообщение от fanatdebian Посмотреть сообщение
поэтому такое присваивание и происходит без проблем.
покажите где такое сработает?
Впрочем, можете не отвечать. Мой вопрос был к человеку который хотя бы понимает о чем пишет.
0
Evg
Эксперт CАвтор FAQ
21204 / 8220 / 633
Регистрация: 30.03.2009
Сообщений: 22,538
Записей в блоге: 30
24.09.2013, 12:34 20
Цитата Сообщение от Evg Посмотреть сообщение
Проблема в том, что в правой части присваивания находится выражение плавающего типа. Любое плавающее выражение обладает побочными эффектами в виде изменения состояния плавающих статусных регистров процессора, которые при определённых установленных масках должны вызывать аппаратное прерывание.

Другими словами, когда мы имеем динамическую инициализацию, то в процессе её вычисления может случиться прерывание и программа попадёт в обработчик прерываний. В случае статической инициализации такое сделать невозможно: компилятор не знает, взведены ли биты, отвечающие за прерывания, не знает, есть ли вообще обработчик прерывания. И может получиться так, что программа со статической и динамической инициализацией будет вести себя по разному. Поэтому запретили плавающие выражения в качестве статических инициализаторов
Чота я по ходу глупость сморозил, в очередной раз невнимательно посмотрев на тест. Тут речь вообще шла о языке Си. В языке Си в качестве инициализатора может быть только константное выражение. В исходном примере в правой части использовалась переменная, а потому с точки зрения языка Си выражение не является константным (хотя в Си++ такое допустимо и будет работать). Правда в printf'е нужно использовать %f, а не %lf, но это мелочи.

Сейчас попытаюсь сообразить, к каким же случаям применяется то, чего я понаписал

Добавлено через 7 минут
Цитата Сообщение от Evg Посмотреть сообщение
Сейчас попытаюсь сообразить, к каким же случаям применяется то, чего я понаписал
Из всего того, что пришло в голову, ничего под это не попадает. По ходу дела я что-то с чем-то спутал. Каюсь
1
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
24.09.2013, 12:34

Ошибка: невозможно преобразовать "initializer list" в "char"
Помогите пожалуйста . Мой код: #ifndef VEC_H #define VEC_H #include &lt;memory&gt; #include...

Ошибка при компиляции "Syntax error "Begin" expected but ";" found"
При компиляции выдаёт ошибку &quot;Syntax error &quot;Begin&quot; expected but &quot;;&quot; found&quot; в блоке Procedure...

При компиляции выскакивает ошибка "оператор == не может применяться к операндам типа "Т" и "Т"
Есть обобщённый метод public Boolean In(T element) { flag = false; foreach (T el in...

Инициализация массива: ошибка "array must be initialized with a brace-enclosed initializer"
Вот собственно сама ошибка: &quot;array must be initialized with a brace-enclosed initializer&quot; Сама...


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2021, vBulletin Solutions, Inc.