Ответ 1
TL; DR Компиляторы C не предупреждают, потому что они не видят проблему там. По определению, строковые литералы C имеют нулевое завершение char
массивов. Он только заявил, что
[...] Если программа пытается изменить такой массив, поведение undefined.
Итак, в процессе компиляции компилятор не знает, что массив char
должен вести себя как строковый литерал или строка. Только попытка модификации запрещена.
Связанное чтение: для любого, кого интересует, см. Почему C-строковые литералы доступны только для чтения?
Тем не менее, я не очень уверен, что это хороший вариант, но gcc
имеет параметр -Wwrite-strings
.
Цитирование онлайн-руководство,
-Wwrite-strings
При компиляции C задайте строковые константы типа
const char[length]
, так что копирование адреса одного в указатель неconst char *
вызывает предупреждение. Эти предупреждения помогут вам найти код времени компиляции, который может попытаться записать в строчную константу, но только если вы были очень осторожны в использовании const в объявлениях и прототипах. В противном случае это всего лишь неприятность. Вот почему мы не запрашивали эти предупреждения-Wall
.
Таким образом, он выдает предупреждение, используя бэкдор-путь.
По определению, строковые литералы C (то есть литералы символьной строки) являются char
массивами с нулевым терминатором. Стандарт не позволяет им быть const
квалифицированным.
Ссылка: C11
, глава
В фазе 7 перевода байт или код нулевого значения добавляется к каждому мультибайту последовательность символов, которая получается из строкового литерала или литералов. Многобайтовый символ последовательность используется для инициализации массива статической продолжительности хранения и длины достаточный для того, чтобы содержать последовательность. Для символьных строковых литералов элементы массива имеют введите
char
и инициализируются отдельными байтами многобайтового символа последовательность. [....]
Использование вышеуказанной опции делает строковые литералы const
квалифицированными так, используя строковый литерал, так как RHS присвоения указателю неконтекстного типа вызывает предупреждение.
Это делается со ссылкой на C11
, глава §6.7.3
Если предпринимается попытка изменить объект, определенный с помощью типа const, используя lvalue с неконстанционно-квалификационным типом, поведение undefined. [...]
Итак, здесь компилятор выдает предупреждение для присвоения const
квалифицированного типа неквалифицированному типу <<29 > .
Связано с тем, почему использование -Wall -Wextra -pedantic -std=c11
не вызывает этого предупреждения, цитирует цитату еще раз
[...] Эти предупреждения помогут вам найти код времени компиляции, который может попытаться записать в константу строки, но только если вы были очень осторожны в использовании констант в объявлениях и прототипах. В противном случае это всего лишь неприятность. Вот почему мы не запрашивали эти предупреждения
-Wall
.