Подтвердить что ты не робот

G++ 4.7 оценивает оператор "" как родственный к макрорасширению

Я переместил некоторый код в GCC 4.7 (из 4.6) и столкнулся с несколькими ошибками компилятора и нашел проблему, описанную в руководстве по переносу GCC 4.7:

Пользовательские литералы и пробелы

Компилятор С++ в режиме ISO C11 std={c++11,c++0x,gnu++11,gnu++0x}поддерживает определенные пользователем литералы, которые несовместимы с некоторыми действительными ISO С++ 03.

В частности, после строкового литерала теперь требуется пробел прежде чем что-то, что может быть допустимым литеральным пользователем. Возьмите действительный код ISO С++ 03

const char *p = "foobar"__TIME__;

В С++ 03 макрос TIME расширяется до некоторого строкового литерала и соединенный с другим. В С++ 11 __TIME__ не расширяется, вместо этого operator "" __TIME__ просматривается, в результате чего после диагностики:

error: unable to find string literal operator  ‘operator"" __TIME__’

Это относится к любому строковому литералу, за которым следуют без пробелов некоторые макро. Чтобы исправить это, просто добавьте пробелы между строковым литералом и имя макроса.

Пока я мог исправить ошибки, я хотел бы знать, почему я должен это делать. __TIME__ - это макрос, поэтому "something"__TIME__ изменится на "something""15:52:03" (или аналогичный) на этапе предварительной обработки, поэтому у компилятора никогда не будет возможности увидеть его как operator "".

Является ли это стандартизированным поведением или это ошибка?

4b9b3361

Ответ 1

Проблема заключается в том, что "foobar"__TIME__ больше не токенируется в токенах препроцессора "foobar", а затем __TIME__.

Знаки препроцессора "имеют лексическую форму ключевого слова, идентификатора, литерала, оператора или пунктуатора." Добавление пользовательских литералов изменяет то, что лексируется как токен препроцессора. Теперь "foobar"__TIME__ представляет собой однозначный токен препроцессора, определяемый пользователем, и поэтому, когда происходит фаза 4 перевода, которая заменила бы __TIME__ на "15:52:03", токер __TIME__ не будет заменен таким образом.

Да, это поведение указано в стандарте.

Из-за макросов cinttypes это похоже на то, что на него влияет больше кода, чем комитет понял, и они рассматривают его. Некоторые компиляторы уже перемещаются, чтобы справляться с проблемами с cinttypes, но не таким образом, чтобы это исправить это использование __TIME__ для вас. Я считаю, что лучше всего изменить код.