Document Number: N2251=07-0111
2007-04-18
Alisdair Meredith <alisdair.meredith@uk.renaultf1.com>
Jens Maurer <Jens.Maurer@gmx.net>

C99 Compatibility : __func__ and predeclared identifiers (revision 1)

1. Intent

The 1999 revision of the C standard introduced the concept of 'a predeclared identifier'.

This feature is used capture function names as string literals, to assist diagnostic libraries. This small change seems preferable to changing the preprocessor to provide equivalent functionality, educating it to parse function definitions in along the way.

Although it would seem expensive to introduce a string literal for every function, it should be relatively simple to optimise the literal away in the majority of cases where the function never refers to it. Likewise the proposal mandates that the literal is simply the unqualified name of the function, so overload sets could all share the same representation of the literal.

In writing up the proposal the format of the literal has been deliberately specified, as an implementation defined string is less helpful in when trying to write a portable diagnostic library facility. The unadorned function name seems the least controversial representation. It is the lowest common denominator and has the benefit of being the same format as would be emitted by a C99 compiler. Awkward cases such as constuctors, destructors and conversion operators are addressed explicitly.

It would be quite possible for vendors to offer additional predefined identifiers using similarly reserved names (eg using double underscores) This would allow vendors to supply more information about the signature if they preferred, namespace or class idenfiers etc. While such extensions would be conforming, they are not a required by for this proposal.

The final point of note is that the library text for the C99 assert macro was updated to require the value of __func__, as will as __FILE__ and __LINE__. As C++ includes the C90 standard and C99 standard library by reference no further changes are necessary.

2. Proposed wording

The wording proposed hereinafter relies on the proposed resolution for core issue 452.

Add a new paragraph after 3.3.1 basic.scope.pdecl paragraph 7:

The point of declaration for a function-local predefined variable (8.4 dcl.fct.def) is immediately before the function-body of a function definition.
Change 3.3.2 basic.scope.local paragraph 2 as indicated:
The potential scope of a function parameter name or of a function-local predefined variable in a function definition (8.4 dcl.fct.def) begins at its point of declaration. If the function has a function-try-block the potential scope of a parameter or function-local predefined variable ends at the end of the last associated handler, else otherwise it ends at the end of the outermost block of the function definition. ...
At the end of 8.4 dcl.fct.def, add new paragraphs:
In the function-body, a function-local predefined variable denotes a local object of static storage duration that is implicitly defined (see 3.3.2 basic.scope.local for its scope).

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. [ Footnote: Implementations are encouraged to provide additional predefined variables with names that are reserved to the implementation (17.4.3.1.2 global.names). If a predefined variable is not used (3.2 basic.def.odr), its string value need not be present in the program image. ]

[ Example:

struct S {
  S() : s(__func__) { }            // ok
  const char *s;
};
void f(const char * s = __func__); // error: __func__ is undeclared
]