Причиной этой проблемы (которую еще сложнее обнаружить, чем проблему, char* str = "some string"которую объяснили другие) является то, что вы используете constexpr.
constexpr char* str = "some string";
Кажется, что он будет вести себя подобно const char* str, и поэтому не будет вызывать предупреждение, как это происходит раньше char*, но вместо этого он ведет себя как char* const str.
подробности
Указатель константы и указатель на константу. Разницу между const char* strи char* const strможно объяснить следующим образом.
const char* str: Объявить str указателем на const char. Это означает, что данные, на которые этот указатель указывает на него, постоянны. Указатель можно изменить, но любая попытка изменить данные приведет к ошибке компиляции.
str++ ;: ДЕЙСТВИТЕЛЬНО . Мы модифицируем указатель, а не данные, на которые указывают.
*str = 'a';: Недействительно . Мы пытаемся изменить данные, на которые указывают.
char* const str: Объявляем str константным указателем на char. Это означает, что точка теперь постоянна, но данные, на которые указывают, тоже нет. Указатель нельзя изменить, но мы можем изменить данные, используя указатель.
str++ ;: Недействительно . Мы пытаемся изменить указатель переменной, которая является константой.
*str = 'a';: ДЕЙСТВИТЕЛЬНО . Мы пытаемся изменить данные, на которые указывают. В нашем случае это не вызовет ошибки компиляции, но вызовет ошибку времени выполнения , поскольку строка, скорее всего, попадет в секцию только для чтения скомпилированного двоичного файла. Это утверждение имело бы смысл, если бы у нас была динамически распределенная память, например. char* const str = new char[5];,
const char* const str: Объявляем str константным указателем на константный символ. В этом случае мы не можем ни изменить указатель, ни данные, на которые он указывает.
str++ ;: Недействительно . Мы пытаемся изменить указатель переменной, которая является константой.
*str = 'a';: Недействительно . Мы пытаемся изменить данные, указанные этим указателем, который также является постоянным.
В моем случае проблема заключалась в том, что я ожидал, что буду constexpr char* strвести себя так const char* str, а не так char* const str, поскольку визуально он кажется ближе к первому.
Кроме того, предупреждение, сгенерированное для constexpr char* str = "some string", немного отличается от char* str = "some string".
- Предупреждение компилятора для
constexpr char* str = "some string":ISO C++11 does not allow conversion from string literal to 'char *const'
- Предупреждение компилятора для
char* str = "some string": ISO C++11 does not allow conversion from string literal to 'char *'.
Наконечник
Вы можете использовать C gibberish ↔ английский конвертер для преобразования Cобъявлений в легко понятные английские выражения, и наоборот. Это Cединственный инструмент, и поэтому он не будет поддерживать вещи (например, constexpr), которые являются эксклюзивными для C++.
strncpy(str, func, 255)вместоstrcpy(str, func)более безопасной копии. И затем не забудьте добавить '\ 0' в конце строки, так как strncpy не добавляет его.