Инициализация неконстантной статической строки с помощью constexpr - PullRequest
0 голосов
/ 08 апреля 2019

Правильно ли следующий код?

constexpr char s[] = "a, bb, ccc";
static const char * s1 = s;
char * s2 = const_cast<char *>(s1);
s2[5] = 'x';

Моя первая идея состояла в том, что 's' существует только во время компиляции и 's1', вероятно, является своего рода копией 's', но, вероятно, этоне совсем корректно, потому что строка 2 не компилируется без 'const':

static char * s1 = s;

Ошибка с MSCV2017: «инициализация»: невозможно преобразовать из «const char [11]» в «char [11]'.

, поэтому неясно, какова связь между' s 'и' s1 '?Они ссылаются на один и тот же строковый литерал?

Ответы [ 2 ]

2 голосов
/ 08 апреля 2019

Определение

static const char * s1 = s;

равно

static const char * s1 = &s[0];

То есть вы s1 указываете на первый элемент s, вот и все. Там не делается "копия".

Вот почему вы не можете использовать указатели на неконстантные (то есть char *), поскольку s1 будет указывать на постоянные данные.

И именно поэтому s2[5] = 'x' приведет к неопределенному поведению при попытке изменить постоянные данные.

1 голос
/ 08 апреля 2019

Моя первая идея состояла в том, что 's' существует только во время компиляции

Нет, оно также существует во время выполнения.constexpr не означает «только во время компиляции».Это означает, что «s должен быть инициализирован с помощью константного выражения» (в основном, константы времени компиляции), что означает, что сам по себе может использоваться и в константных выражениях.

's1'вероятно, это какая-то копия' s '

s1 просто указывает на первый символ массива s.Это не копия содержимого массива.

строка 2 не компилируется без 'const':

Вы не можете сделать это без const_cast- но вы все равно не захотите, потому что изменение оригинальной переменной const (то есть s) - это неопределенное поведение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...