Предупреждение ISO C++ forbids converting a string constant to 'char*' [-Wwrite-strings] появляется при компиляции кода вида char s = "hello"; в GCC или Clang: строковый литерал имеет тип const char[], а присваивание его обычному указателю char нарушает константность и открывает путь к неопределённому поведению при попытке записи. Компилятор допускает такое присваивание ради совместимости со старым кодом на C, но флаг -Wwrite-strings (включённый напрямую или через -Wall в C++) заставляет его сообщать о проблеме.

Ошибка типична для проектов, портированных со старого C на C++, для учебных примеров и для кода, где функции объявлены с параметром char*, хотя изменять строку они не собираются. Ниже разберём, почему стандарт запрещает такое преобразование, какие способы исправления безопасны, а какие лишь маскируют проблему.

Почему строковый литерал нельзя присваивать char*

Строковые литералы вроде "hello" компилятор обычно размещает в области памяти, доступной только для чтения (например, в секции .rodata исполняемого файла). Стандарт C++ прямо указывает: попытка модифицировать строковый литерал — это неопределённое поведение. На практике запись в такую память чаще всего завершается аварийным завершением программы с ошибкой сегментации.

Тип литерала "hello" — это массив const char[6]. Когда вы пишете char *s = "hello";, происходит неявное снятие константности, чего система типов допускать не должна. В старом C это было разрешено исторически, а C++ унаследовал послабление только как устаревшее исключение — с предупреждением.

💡

Строковый литерал — это const char[]. Присваивание его char* снимает константность и делает возможной запись в память, предназначенную только для чтения.