__func__ определение внешней функции
Что произойдет, если мы используем предопределенную переменную __func__
вне функции в C (C99/C11) и С++?
#include <stdio.h>
const char* str = __func__;
int main(void)
{
printf("%s", str);
return 0;
}
gcc 4.7.2 только выдает предупреждение (при включенном -Wall -W -pedantic
) и ничего не печатает.
Стандарт ничего не говорит об этом явно:
ISO/IEC 14882: 2011
8.4.1 Обычно [dcl.fct.def.general]
8 Локальная предопределенная переменная __func__
определяется как если бы определение формы static const char __func__[] = "function-name";
, где имя функции является определяемой реализацией строка. Не указано, имеет ли такая переменная адрес отличной от функции любого другого объекта в программе.
ISO/IEC 9899: 2011
6.4.2.2 Предопределенные идентификаторы
1 Идентификатор __func__
должен быть неявно объявлен переводчиком так, как будто, немедленно после открытия скобки каждого определения функции, декларация static const char __func__[] = "function-name";
появился, где function-name - это имя лексически-охватывающего функция.
UB? Ошибка? Или что-то еще?
Ответы
Ответ 1
Стандарт ничего не говорит об этом явно
Это означает поведение undefined.
Из стандарта C (ударный удар):
(C99, 4.p2) "Если" a "или" не будет требовать, чтобы внешнее ограничение было нарушено, поведение undefined. undefined поведение иначе указано в настоящем стандарте слова "undefined поведение или упущение какого-либо явного определения поведения. Нет никакой разницы в акценте среди этих трех: все они описывают поведение" undefined ".
Ответ 2
(продвигается из более раннего комментария)
__func__
находится в зарезервированном пространстве имен, поэтому реализации разрешено использовать его в области пространства имен для любой цели, то есть реализация не требуется для диагностики (неправильного) использования __func__
вне функции, потому что ничего в стандарте запрещает реализацию от определения __func__
в качестве массива области пространства имен char
, если это то, что хотят сделать разработчики.
Это может быть undefined, или его можно определить как строку или как что-либо еще, и эта реализация по-прежнему соответствует.
Таким образом, поведение undefined пытается использовать его вне функции, потому что оно может или не может быть определено и может быть или не быть подходящим типом для использования.
Для конкретных примеров того, как код в вопросе мог иметь поведение undefined при использовании с соответствующей реализацией, я полагаю, что реализация могла бы определить его на nullptr
(так что пример потерпит крах в printf
) или может даже определите его макросу, который расширяется до разыменования нулевого указателя, а затем #undef
он при входе каждой функции и #define
после каждой функции (так что пример потерпит крах до начала main
!)