Ошибка оператора Stringize

С и все стандарты C ++ включают в себя текст о том, что если операция stringize не может создать корректный токен строкового литерала, поведение не определено. В C ++ 11 это действительно возможно, если включить символ новой строки в необработанный строковый литерал. Но главное в стандартах всегда было.

Есть ли другой способ, которым stringize может создать UB, где UB или плохо сформированная программа еще не произошли?

Мне было бы интересно услышать о любом диалекте С или C ++ вообще. я пишу препроцессор.

7

Решение

Стрификация (#) оператор только убегает \ в строковых константах. В самом деле, \ не имеет особого значения вне строковой константы, кроме как в конце строки. Следовательно, это токен предварительной обработки (C-раздел 6.4, C ++-раздел 2.5).

Следовательно, если мы имеем

#define Q(X) #X

затем

Q(\)

законный вызов: \ токен предварительной обработки, который никогда не преобразуется в токен, поэтому он действителен Но вы не можете зачеркнуть \; это даст вам «\», который не является допустимым строковым литералом. Следовательно, поведение вышеописанного не определено.

Вот более забавный тестовый пример:

#define Q(A) #A
#define ESCAPE(c) Q(\c)
const char* new_line=ESCAPE(n);
const char* undefined_behaviour=ESCAPE(x);

Менее интересный случай неопределенной stringify — это когда параметр stringified будет слишком длинным, чтобы быть строковым литералом. (Стандарты рекомендуют, чтобы максимальный размер строкового литерала составлял не менее 65536 символов, но ничего не говорится о максимальном размере макро-аргумента, который предположительно может быть больше.)

4

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]