22

What should happened if we use predefined variable __func__ outside a function in C (C99 / C11) and C++?

#include <stdio.h>

const char* str = __func__;

int main(void)
{
   printf("%s", str);
   return 0;
}

gcc 4.7.2 only give a warning (with -Wall -W -pedantic enabled) and prints nothing.

Standard doesn't say anything about it explicitly:

ISO/IEC 14882:2011

8.4.1 In general [dcl.fct.def.general]

8 The function-local predefined variable __func__ is defined as if a definition of the form static const char __func__[] = "function-name"; had been provided, where function-name is an implementation-defined string. It is unspecified whether such a variable has an address distinct from that of any other object in the program.

ISO/IEC 9899:2011

6.4.2.2 Predefined identifiers

1 The identifier __func__ shall be implicitly declared by the translator as if, immediately following the opening brace of each function definition, the declaration static const char __func__[] = "function-name"; appeared, where function-name is the name of the lexically-enclosing function.

UB? Error? Or something else?

leemes
  • 44,967
  • 21
  • 135
  • 183
FrozenHeart
  • 19,844
  • 33
  • 126
  • 242
  • 1
    I vote for error, given the wording "function-local predefined variable" and "immediately following the opening brace of each function definition" in your quotations. – jpalecek Jan 02 '13 at 13:58
  • 9
    Any behaviour not defined by the standard is, by elimination, undefined behaviour ;) – Oliver Charlesworth Jan 02 '13 at 13:58

2 Answers2

24

Standard doesn't say anything about it explicitly

This means undefined behavior.

From the C Standard (emphasis mine):

(C99, 4.p2) "If a ‘‘shall’’ or ‘‘shall not’’ requirement that appears outside of a constraint is violated, the behavior is undefined. Undefined behavior is otherwise indicated in this International Standard by the words ‘‘undefined behavior’’ or by the omission of any explicit definition of behavior. There is no difference in emphasis among these three; they all describe ‘‘behavior that is undefined’’."

ouah
  • 142,963
  • 15
  • 272
  • 331
7

(Promoted from an earlier comment)

__func__ is in the reserved namespace, so the implementation is allowed to use it at namespace scope for any purpose, i.e. the implementation is not required to diagnose a (mis)use of __func__ outside a function, because nothing in the standard forbids an implementation from defining __func__ as a namespace-scope array of char if that's what the implementors want to do.

It could be undefined, or it could be defined as a string, or as anything else, and that implementation is still conforming.

So it's undefined behaviour to try to use it outside a function because it may or may not be defined and may or may not be of the right type to be usable.

For concrete examples of how the code in the question could have undefined behaviour when used with a conforming implementation, I believe an implementation could define it to nullptr (so the example would crash in printf) or could even define it to a macro that expands to a dereference of a null pointer and then #undef it on entry to each function and #define it after each function (so the example would crash before main begins!)

Jonathan Wakely
  • 166,810
  • 27
  • 341
  • 521