Причиной этой проблемы (которую еще сложнее обнаружить, чем проблему, 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 не добавляет его.