gooblin:
Korben_Dallas:
но в C++17 компиляторах, подчиняющихся требованиям Itanium ABI,
каким боком ABI к стандарту C++? Любое ABI - штука платформо-зависимая, на то оно и ABI. Для других платформ можно в ABI тоже найти парочку чудес. Но это все непереносимо.
Да, но ABI не должно нарушать стандарт языка. Однако в данном случае все получилось наоборот. И стандарты все-таки не в вакууме пишутся.
Стандарт С++ вплоть до С++14 требовал, чтобы параметры функций уничтожались в контексте вызывающего года сразу после возврата из функции (С++14 5.2.2/4: "The lifetime of a parameter ends when the function in which it is defined returns. The initialization and destruction of each parameter occurs within the context of the calling function." )
А авторы Itanium ABI настояли на том, что параметры функций должны продолжать жить до конца полного выражения, содержащего вызов функции (это якобы предоставляет ряд полезных оптимизационных возможностей). Компиляторы юниксового толка (GCC, Clang) поклялись в верности Itanium ABI и стали откладывать момент уничтожения параметров до конца полного выражения. Тем самым они нарушали требования стандарта С++.
Это привело к появлению C++ Defect Report 1880 (http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1880) в стиле "чё теперь делать-то будем?"
В конечном итоге "прогнулся" стандарт С++ и начиная с С++17 вышепроцитированный текст был заменен на "It is implementation-defined
whether the lifetime of a parameter ends when the function in which it is defined returns or at the end of the enclosing full-expression."
В компиляторах GCC и Clang это "implementation-defined" определяется именно Itanium ABI. В этих компиляторах нет никакого UB в возвращении ссылок/указателей на параметры функции, пока эти ссылки/указатели используются в течение времени жизни объекта (т.е. до конца полного вызывающего выражения, как в приведенном мною примере). Но в GCC до сих пор болтается пережиток прошлого - он в таких случаях нагло подставляет возврат нулевой ссылки/указателя, что и демонстрируется моим примером.
Добавлено спустя 21 минута 51 секунда
Mahagam:
я ещё тогда просто провёл натурный эксперимент. если обьявлять как static char *p = "Hello"; то всё возвращается корректно (указатель на "Hello"), без static - указатель точно ненулевой, потому что выводится фигня, а не "Hello". среда разработки NI LаbWindоws.
и логика в этом прослеживается.
Ну это ж совсем другое. Ваш `static` тут вообще ни на что не влияет. А сам строковый литерал в С и С++ является и всегда являлся массивом со статическим классом памяти. То есть никакого возврата указателей на локальные данные тут нет и к исходной теме это никак не относится. Ключевым моментом моего примера являлся именно локальный массив.