из племени тумба-юбма
|
|||||||||||
1 | |||||||||||
Объявление массива - Компилятор не воспринимает константу09.12.2020, 23:07. Просмотров 1853. Ответов 17
Метки нет Все метки)
(
вот если такой вариант в коде:
Но если сделаю так:
0
|
|
09.12.2020, 23:07 | |
Почему компилятор не воспринимает define константу Компилятор не воспринимает метод Компилятор не воспринимает FindWindow Компилятор не воспринимает русские буквы |
|
из племени тумба-юбма
|
|||||||||||
10.12.2020, 15:12 [ТС] | 3 | ||||||||||
странно в онлайн компиляторе, такой код:
Код
main.c: In function ‘main’: main.c:7:5: error: variable-sized object may not be initialized char s[N] = "qwert"; ^~~~
Наверно это как то связано с установленным у меня префиксом -Werror=vla . Видимо данный префикс разрешает только препроцессорные константы типа define, а все остальное считает переменными.
0
|
170 / 130 / 51
Регистрация: 18.07.2017
Сообщений: 682
|
|||||||||||
11.12.2020, 11:38 | 4 | ||||||||||
"qwert" - const char*. Следовательно данные по этому указателю не изменяются. А раз они не изменяются, то нет и смысла выделять больше памяти чем требуется для указанной строки. На это намекает допустимость таких конструкций:
0
|
![]() 25203 / 15683 / 3349
Регистрация: 24.12.2010
Сообщений: 34,162
|
|||||||||||
11.12.2020, 12:14 | 5 | ||||||||||
assemberist, насколько мне известно,
Вот такое вполне работает
0
|
170 / 130 / 51
Регистрация: 18.07.2017
Сообщений: 682
|
|
11.12.2020, 13:30 | 6 |
Да, переменные вычисляются и используются в рантайме, а дефайны подставляются на этапе компиляции. Похоже раз компилятор не может определить во время компиляции размер массива, то не может ручаться за то поместится ли туда какое либо значение. Поэтому такой финт запрещен.
0
|
170 / 130 / 51
Регистрация: 18.07.2017
Сообщений: 682
|
|
11.12.2020, 16:27 | 8 |
const int N - переменная (неизменяемая). А поскольку:
то, компилятор не может определить во время компиляции размер массива. Но я не знаю как на такую ситуацию смотрит стандарт: это ошибка или разработчики компилятора вправе разрешать такие ситуации на свое усмотрение.
0
|
96 / 98 / 30
Регистрация: 21.10.2012
Сообщений: 320
|
||||||
12.12.2020, 18:27 | 9 | |||||
Самое интересное это то, что компилятор gcc не позволяет задавать константный размер массива при помощи квалификатора const, а компилятор clang разрешает так делать и не выдаёт никаких ошибок.
В общем, этот кусок кода в gcc выдаёт ошибку: variable-sized object may not be initialized А компилятор clang это спокойно кушает и абсолютно не возмущается.
0
|
12.12.2020, 19:00 | 10 |
Denno, Уровень оптимизации надеюсь 0? А то мало ли что там в компилерах есть - если в проге нет обращения к памяти по указателю на константную переменную - могут оптимиировать её в дефайн и впилить прямо в код программы.
З.Ы. Да. Тут надо лезть в стандарт, и походу там может нарисоваться UB. Логически - Си может через разыменование указателей изменить const переменную (если ОС или железо в контроллёрах не проследит за этим)
0
|
![]() 25203 / 15683 / 3349
Регистрация: 24.12.2010
Сообщений: 34,162
|
|||||||||||
12.12.2020, 19:25 | 11 | ||||||||||
С этими массивами дело темное. В первозданном Си массив можно было задавать только так
Следом за Си решили и в С++ это устандартить.. И в каком-то стандарте так и было. Потом спохватились, что-то там не состыковывалось, и из стандарта выключили. Оставили на усмотрении разработчикам трансляторов. А в чистом Си, кажись, так и осталось... Так что если хотите спокойной и независимой жизни, лучше эту фичу нигде не применять. Применяете? Будто готовы разбираться с компиляторами вместо того чтобы делом заниматься.
0
|
12.12.2020, 19:37 | 12 |
Согласен. Непоняток лучше избегать.
Кстати, может быть разница в поведении среди локальных и глобальных массивов. Локальный - как раз таки можно выделить в стеке по реальной переменной "в процессе вычисления", а вот глобальный - только на этапе компиляции.
0
|
из племени тумба-юбма
|
|||||||||||
12.12.2020, 19:42 [ТС] | 13 | ||||||||||
Да причем тут фича с локальной переменной?
Речь идет о константных переменных
0
|
170 / 130 / 51
Регистрация: 18.07.2017
Сообщений: 682
|
||||||
13.12.2020, 00:59 | 15 | |||||
Во втором случае во время компиляции все N заменяются на 10. А в первом N - полноценная переменная. Да, const int - такая же переменная как и просто int. И значение она имеет лишь в рантайме. Так что ее нельзя заменить на 10 просто так.
Потому что ничто не мешает мне сделать вот так:
0
|
из племени тумба-юбма
|
|
13.12.2020, 01:22 [ТС] | 16 |
тогда я снова в ступоре и совсем не понимаю назначение типа const, если оно изменяемое
![]() Добавлено через 2 минуты хотя, в вашем коде, вы же переменную j, каждый раз объявляете заново, тогда наверно возможно
0
|
170 / 130 / 51
Регистрация: 18.07.2017
Сообщений: 682
|
|
13.12.2020, 01:43 | 17 |
Самое известное применение - const char*. В данном случае запрещается менять данные по указателю, но можно читать и копировать и менять положение самого указателя.
Оно неизменяемое во время жизни const переменной.
1
|
13.12.2020, 10:05 | 18 | |||||
Прикол про разыменование:
0
|
13.12.2020, 10:05 | |
Заказываю контрольные, курсовые, дипломные и любые другие студенческие работы здесь. Объявление графа через входной файл или константу Оптимизирует ли компилятор код при использовании функции, возвращающей константу? Компилятор не распознает объявление класса Компилятор не видит объявление класса Компилятор не видит объявление идентификатора
Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |