Ответ 1
Во-первых, тип строковых литералов: все они являются постоянными массивами их типа символов.
2.14.5 Строковые литералы [lex.string]
7 Строковый литерал, начинающийся с u8, такой как u8 "asdf", является строковым литералом UTF-8 и инициализируется заданными символами, закодированными в UTF-8.
8 Обычные строковые литералы и строковые литералы UTF-8 также называются узкими строковыми литералами. Узкий строковый литерал имеет тип "массив из n const char", где n - размер строки, как определено ниже, и имеет статическую продолжительность хранения (3.7).
9 Строковый литерал, начинающийся с u, такой как u "asdf", является строковым литералом char16_t. Строковый литерал char16_t имеет тип "array of n const char16_t", где n - размер строки, как определено ниже; он имеет статическую продолжительность хранения и инициализируется заданными символами. Один c- char может генерировать более одного символа char16_t в виде суррогатных пар.
10 Строковый литерал, начинающийся с U, такой как U "asdf", является строковым литералом char32_t. Строковый литерал char32_t имеет тип "array of n const char32_t", где n - размер строки, как определено ниже; он имеет статическую продолжительность хранения и инициализируется заданными символами.
11 Строковый литерал, начинающийся с L, такой как L "asdf", является строковым литералом. Широкий строковый литерал имеет тип "array of n const wchar_t", где n - размер строки, как определено ниже; он имеет статическую продолжительность хранения и инициализируется заданными символами.
Далее, давайте увидим, что мы имеем только стандартный распад массива, поэтому от T[#]
до T*
:
4.2 Преобразование массива в указатель [conv.array]
1 lvalue или rvalue типа "массив из N T" или "массив неизвестной границы T" можно преобразовать в prvalue типа "указатель на T". Результатом является указатель на первый элемент массива.
И, наконец, давайте увидим, что любое соответствующее расширение не должно изменять значение правильной программы:
1.4 Соответствие требованиям [intro.compliance]
1 Набор диагностируемых правил состоит из всех синтаксических и семантических правил в этом Международном стандарте, за исключением тех правил, которые содержат явное обозначение, что "никакой диагностики не требуется" или которые описаны как результат "undefined поведения". < ш > 2 Хотя в этом международном стандарте утверждены только требования к реализациям на С++, эти требования часто легче понять, если они сформулированы как требования к программам, частям программ или выполнению программ. Такие требования имеют следующее значение:
- Если программа не содержит нарушений правил в этом Международном стандарте, соответствующая реализация должна в пределах своих ресурсов принимать и правильно выполнять эту программу.
- Если программа содержит нарушение любого диагностируемого правила или появление конструкции, описанной в этом стандарте, как "условно поддерживаемая", когда реализация не поддерживает эту конструкцию, соответствующая реализация должна выпустить хотя бы одно диагностическое сообщение.
- Если программа содержит нарушение правила, для которого не требуется диагностика, этот Международный Стандарт не требует каких-либо требований к реализации в отношении этой программы.
Итак, в итоге, это ошибка компилятора.
(До С++ 11 (С++ 03) преобразование было разрешено, но устарело, поэтому было бы правильно. Диагностика в случае, если это произошло, не требовалось бы, а предоставлялось как проблема качества реализации.)
Это ошибка GCC, а также ошибка clang.
Отчет об ошибке для clang: http://llvm.org/bugs/show_bug.cgi?id=16314 (Благодаря TC для поиска отчета об ошибке.)
Тест файл из отчета об ошибке clang, который намного короче:
void f(char*);
int &f(...);
int &r = f("foo");