The variable __func__ in C89 in gcc

N

none

Consider:

#include <stdio.h>
int main(void)
{
printf("entering function %s\n", __func__);
return 0;
}

Gcc compiles this program without a warning, even
in C89 mode, as in "gcc -Wall -pedantic -std=c89 progname.c".

I expected to see a warning since the identifier __func__ was
introduced in C99. Is there a good reason why the compilation
does not fail in the C89 mode?
 
S

Shao Miller

Consider:

#include<stdio.h>
int main(void)
{
printf("entering function %s\n", __func__);
return 0;
}

Gcc compiles this program without a warning, even
in C89 mode, as in "gcc -Wall -pedantic -std=c89 progname.c".

I expected to see a warning since the identifier __func__ was
introduced in C99. Is there a good reason why the compilation
does not fail in the C89 mode?

What would _prevent_ GCC from providing this for C89 code?
 
S

Seebs

#include <stdio.h>
int main(void)
{
printf("entering function %s\n", __func__);
return 0;
}

Gcc compiles this program without a warning, even
in C89 mode, as in "gcc -Wall -pedantic -std=c89 progname.c".

I expected to see a warning since the identifier __func__ was
introduced in C99. Is there a good reason why the compilation
does not fail in the C89 mode?

Your code has undefined behavior. Why should you have any expectations
about what it does? :)

__func__ is in the implementation's namespace. There is no lack of compliance
with C89 if the implementation happens to define things in its own reserved
namespace...

-s
 
K

Keith Thompson

Seebs said:
Your code has undefined behavior. Why should you have any expectations
about what it does? :)

__func__ is in the implementation's namespace. There is no lack of
compliance with C89 if the implementation happens to define things in
its own reserved namespace...

On the other hand, it would certainly be polite for gcc to warn about
this, at least in some mode. The standard imposes no obligation to do
so, but gcc *knows* that __func__ specific to C99, and therefore that
any code that uses it is not portable to non-gcc C90 implementations.

Perhaps there's an option to do so; "-Wall" doesn't actually enable
*all* warnings (but a search of the gcc documentation didn't find such
an option).

(By "gcc knows", of course, I mean that the authors know, and could make
use of that knowedge to make gcc issue a warning.)
 
S

Seebs

Just so. If one is writing code with the hope that it is portable to
all conforming C90 compilers it would be sporting if compiler writers
would warn one of their little improvements.

I agree, and I'd prefer that. But I am pretty sure, on thinking about it,
that there is no *required* diagnostic there.

-s
 
S

Sorc Chan

Consider:

#include <stdio.h>
int main(void)
{
        printf("entering function %s\n", __func__);
        return 0;

}

Gcc compiles this program without a warning, even
in C89 mode, as in "gcc -Wall -pedantic -std=c89 progname.c".

I expected to see a warning since the identifier __func__ was
introduced in C99.  Is there a good reason why the compilation
does not fail in the C89 mode?

int main(void) {
__func__;
return 0;
}

$ gcc -S main1.c -Wall -pedantic -std=c89 -o main1.s && cat main1.s
main1.c: In function ‘main’:
main1.c:2: warning: statement with no effect
.file "main1.c"
.text
..globl main
.type main, @function
main:
pushl %ebp
movl %esp, %ebp
movl $0, %eax
popl %ebp
ret
.size main, .-main
.section .rodata
.type __func__.869, @object
.size __func__.869, 5
__func__.869:
.string "main"
.ident "GCC: (GNU) 4.4.4 20100630 (Red Hat 4.4.4-10)"
.section .note.GNU-stack,"",@progbits
$

Dat GCC epic fail IMHO.

Because __func__ in C98 undeclared such as any __ohhelloguys__ thing.
 
T

Tim Rentsch

Seebs said:
Your code has undefined behavior. Why should you have any expectations
about what it does? :)

Presumably because of the stipulations in 5.1.1.3, ie, at least a
diagnostic must be issued.
__func__ is in the implementation's namespace. There is no lack of compliance
with C89 if the implementation happens to define things in its own reserved
namespace...

The problem is the Standard doesn't say that. The Standard talks
about 'reserved identifiers', not an 'implementation namespace'.
"Reserved" means a program may not declare or define them (modulo
section 7.1.7). The section that specifies which identifiers are
reserved (which is 7.1.3) says that they may be declared or
defined in _header files_ (clearly not relevant for __func__),
but AFAICS nothing otherwise. In the absence of any provision
allowing the implementation itself (as opposed to a header file)
to declare or define reserved identifiers, I don't see why we
should suppose that it's allowed to. And of course that would
mean that '__func__' would cause a syntax error, triggering a
diagnostic.

It's quite plausible that the original intention was to allow
implementations to define reserved identifiers however they like.
I just don't see any text in the Standard that grants such a
right.
 
J

James Kuyper

int main(void) {
__func__;
return 0;
}

$ gcc -S main1.c -Wall -pedantic -std=c89 -o main1.s && cat main1.s
main1.c: In function ‘main’:
main1.c:2: warning: statement with no effect
.file "main1.c"
.text
.globl main
.type main, @function
main:
pushl %ebp
movl %esp, %ebp
movl $0, %eax
popl %ebp
ret
.size main, .-main
.section .rodata
.type __func__.869, @object
.size __func__.869, 5
__func__.869:
.string "main"
.ident "GCC: (GNU) 4.4.4 20100630 (Red Hat 4.4.4-10)"
.section .note.GNU-stack,"",@progbits
$

Dat GCC epic fail IMHO.

It might be an "epic failure" to meet some arbitrary requirement that
you've chosen to impose; but it does not indicate a failure to meet the
requirements imposed by the C89 standard.
Because __func__ in C98 undeclared such as any __ohhelloguys__ thing.

C89 imposes no such requirement. In fact, the main reason why the C89
standard said that a program using __func__ has undefined behavior is so
an implementation can choose to do anything it wishes to do with
__func__. In particular, the fact that the behavior is undefined gives
the compiler permission to treat __func__ as behaving in precisely the
fashion it's required to behave, according to the C99 standard. It also
gives it permission to treat __func__ as an indication that it should
use your program to generate Funk music.
 
S

Shao Miller

int main(void) {
__func__;
return 0;
}

$ gcc -S main1.c -Wall -pedantic -std=c89 -o main1.s&& cat main1.s
main1.c: In function ‘main’:
main1.c:2: warning: statement with no effect
.file "main1.c"
.text
.globl main
.type main, @function
main:
pushl %ebp
movl %esp, %ebp
movl $0, %eax
popl %ebp
ret
.size main, .-main
.section .rodata
.type __func__.869, @object
.size __func__.869, 5
__func__.869:
.string "main"
.ident "GCC: (GNU) 4.4.4 20100630 (Red Hat 4.4.4-10)"
.section .note.GNU-stack,"",@progbits
$

Dat GCC epic fail IMHO.


Because __func__ in C98 undeclared such as any __ohhelloguys__ thing.

Is it a documented extension? (See "COMPLIANCE" section.)

Is it incompatible with C89? (See 'man gcc' "-ansi" section and "std="
section.)

Here's some potentially relevant GCC documentation:


http://gcc.gnu.org/onlinedocs/gcc-4.3.5/gcc/Function-Names.html#Function-Names
 
K

Keith Thompson

Tim Rentsch said:
The problem is the Standard doesn't say that. The Standard talks
about 'reserved identifiers', not an 'implementation namespace'.
"Reserved" means a program may not declare or define them (modulo
section 7.1.7). The section that specifies which identifiers are
reserved (which is 7.1.3) says that they may be declared or
defined in _header files_ (clearly not relevant for __func__),
but AFAICS nothing otherwise. In the absence of any provision
allowing the implementation itself (as opposed to a header file)
to declare or define reserved identifiers, I don't see why we
should suppose that it's allowed to. And of course that would
mean that '__func__' would cause a syntax error, triggering a
diagnostic.

It's quite plausible that the original intention was to allow
implementations to define reserved identifiers however they like.
I just don't see any text in the Standard that grants such a
right.

Quibble: It would be a constraint violation, not a syntax error, but
that doesn't affect the argument.

C99 5.1.1.3 explicitly states that violations of syntax rules and
constraints must be diagnosed even in the presence of undefined
behavior. C90 5.1.1.3 does not, and the possible consequences of
undefined behavior include "behaving during translation or program
execution in a documented manner characteristic of the environment
(with or without the issuance of a diagnostic message)" (C90 3.16).

But we're still left with the question of whether a conforming C99
implementation may predefine __foo__ (not in any header). Like you,
I'd say that the intended answer s yes, but I can't prove it from
the standard.
 
S

Seebs

But we're still left with the question of whether a conforming C99
implementation may predefine __foo__ (not in any header). Like you,
I'd say that the intended answer s yes, but I can't prove it from
the standard.

I'm pretty sure it's intended, but interestingly, it seems as though the only
way that intent is expressed is through the undefined behavior you get if you
try to use the identifier.

I guess the thing is...

Obviously:
int __func__;
is undefined behavior; you're using a reserved identifier.

But if you do
printf("%s\n", __func__);
I can't tell whether this is a constraint violation, in that you're referring
to an undeclared identifier, or plain undefined behavior, because you're using
a reserved identifier.

.... You know, every time I look at this again, my expectation flip-flops. I
conclude that the obvious intent of the standard is that each implementation
shall have a cryptographic-quality source of random numbers, and shall
diagnose this in 50% of all cases, unpredictably.

-s
 
S

Shao Miller

I'm pretty sure it's intended, but interestingly, it seems as though the only
way that intent is expressed is through the undefined behavior you get if you
try to use the identifier.

I guess the thing is...

Obviously:
int __func__;
is undefined behavior; you're using a reserved identifier.

But if you do
printf("%s\n", __func__);
I can't tell whether this is a constraint violation, in that you're referring
to an undeclared identifier, or plain undefined behavior, because you're using
a reserved identifier.

... You know, every time I look at this again, my expectation flip-flops. I
conclude that the obvious intent of the standard is that each implementation
shall have a cryptographic-quality source of random numbers, and shall
diagnose this in 50% of all cases, unpredictably.

Perhaps these sections could be relevant to the discussion...

From C89's "COMPLIANCE" section (I believe):

"...A conforming implementation may have extensions (including
additional library functions), provided they do not alter the behavior
of any strictly conforming program..."

Does that suggest that '__func__' could be included in the meaning of
"extensions"? Can a strictly conforming program define '__func__' and
thus have its behaviour altered if the implementation defines it?

From C89's "Predefined macro names" section (I believe):

"...All predefined macro names shall begin with a leading underscore
followed by an upper-case letter or a second underscore..."

From C89's "Standard headers" section (I believe):

"... All other identifiers that begin with an underscore and either
an upper-case letter or another underscore are reserved..."

From C89's "Common extensions" appendix (I believe):

"...The inclusion of any extension that may cause a strictly
conforming program to become invalid renders an implementation
nonconforming. Examples of such extensions are new keywords, or library
functions declared in standard headers or predefined macros with names
that do not begin with an underscore."

Some examples of extensions are then given.

From a foreword associated with C89 (I believe):

"Because external identifiers and some macro names beginning with an
underscore are reserved, implementations may provide special semantics
for such names. For example, the identifier _BUILTIN_abs could be used
to indicate generation of in-line code for the abs function. Thus, the
appropriate header could specify #define abs(x) _BUILTIN_abs(x) for a
compiler whose code generator will accept it. In this manner, a user
desiring to guarantee that a given library function such as abs will be
a genuine function may write #undef abs whether the implementation's
header provides a macro implementation of abs or a builtin
implementation. The prototype for the function, which precedes and is
hidden by any macro definition, is thereby revealed also."

Do these [partial] references suggest that reserved identifiers of the
form '_Xxx' and '__xxx' are free for an implementation to define,
including semantics and behaviour?

Now some GCC documentation which might or might not be relevant:

From GCC 4.3.5's "Extensions to the C Language Family" section (5)[1]:

"...Some features that are in ISO C99 but not C89 or C++ are also, as
extensions, accepted by GCC in C89 mode and in C++..."

From GCC 4.3.5's "Function Names as Strings" section (5.43)[2]:

"...The identifier __func__ is 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."

What are your thoughts on the matter, given these?

[1]
http://gcc.gnu.org/onlinedocs/gcc-4.3.5/gcc/C-Extensions.html#C-Extensions
[2]
http://gcc.gnu.org/onlinedocs/gcc-4.3.5/gcc/Function-Names.html#Function-Names
 
T

Tim Rentsch

Keith Thompson said:
Quibble: It would be a constraint violation, not a syntax error, but
that doesn't affect the argument.

Actually syntax error, because of the rule for when an identifier
is considered to be a primary expression; see 6.5.1p2 (same as
C90 6.3.1, first paragraph under Semantics).
C99 5.1.1.3 explicitly states that violations of syntax rules and
constraints must be diagnosed even in the presence of undefined
behavior. C90 5.1.1.3 does not, and the possible consequences of
undefined behavior include "behaving during translation or program
execution in a documented manner characteristic of the environment
(with or without the issuance of a diagnostic message)" (C90 3.16).

I acknowledge the argument, and it's a reasonable argument. My
counter argument is that the behavior is (partially) defined,
because 5.1.1.3 requires a diagnostic; since nothing explicitly
makes the behavior in this case undefined, translating the program
doesn't fall into the realm of undefined behavior, and a diagnostic
must be issued. I might add, I suspect this confusion was just an
oversight in the writing, and C99 merely corrected the oversight
rather than constituting a change in what's expected for conformance.
But we're still left with the question of whether a conforming C99
implementation may predefine __foo__ (not in any header). Like you,
I'd say that the intended answer s yes, but I can't prove it from
the standard.

Certainly it would be allowed as an extension. I now believe
this avenue is the intended one, ie, reserved identifiers may
be predefined or predeclared if and only if such definitions
and declarations are documented as extensions.
 
T

Tim Rentsch

James Kuyper said:
It might be an "epic failure" to meet some arbitrary requirement that
you've chosen to impose; but it does not indicate a failure to meet the
requirements imposed by the C89 standard.


C89 imposes no such requirement. In fact, the main reason why the C89
standard said that a program using __func__ has undefined behavior is so
an implementation can choose to do anything it wishes to do with
__func__.

Except the C89 standard doesn't say that (nor does the C99
standard). Declaring or defining a reserved identifier
is undefined behavior, but just using one isn't.
In particular, the fact that the behavior is undefined gives
the compiler permission to treat __func__ as behaving in precisely the
fashion it's required to behave, according to the C99 standard.

No, under the C99 standard a diagnostic must be issued.
No diagnostic, no conformance.
It also
gives it permission to treat __func__ as an indication that it should
use your program to generate Funk music.

Only if the implementation defines an extension that
declares or defines __func__; otherwise it's just a syntax
error, no different from saying 'foo;'. Treating it any
differently from any other syntax error may reasonably be
considered an extension, and extensions require the
implementation to document them.
 
T

Tim Rentsch

Shao Miller said:
int main(void) {
__func__;
return 0;
}

$ gcc -S main1.c -Wall -pedantic -std=c89 -o main1.s&& cat main1.s
main1.c: In function 'main':
main1.c:2: warning: statement with no effect
.file "main1.c"
.text
.globl main
.type main, @function
main:
pushl %ebp
movl %esp, %ebp
movl $0, %eax
popl %ebp
ret
.size main, .-main
.section .rodata
.type __func__.869, @object
.size __func__.869, 5
__func__.869:
.string "main"
.ident "GCC: (GNU) 4.4.4 20100630 (Red Hat 4.4.4-10)"
.section .note.GNU-stack,"",@progbits
$

Dat GCC epic fail IMHO.


Because __func__ in C98 undeclared such as any __ohhelloguys__ thing.

Is it a documented extension? [snip]

A good point. Thank you for bringing this consideration
into the discussion.
 
K

Keith Thompson

Tim said:
James said:
On 18 <<D0>> <<BC>> <<D0>> <<B0>> <<D0>> <<B9>> , 18:08, rouben@shady.(none) (Rouben Rostamian) wrote:
Consider:

#include <stdio.h>
int main(void)
{
printf("entering function %s\n", __func__);
return 0;

} [...]
What would _prevent_ GCC from providing this for C89 code?

Because __func__ in C98 undeclared such as any __ohhelloguys__ thing.

C89 imposes no such requirement. In fact, the main reason why the C89
standard said that a program using __func__ has undefined behavior is so
an implementation can choose to do anything it wishes to do with
__func__.

Except the C89 standard doesn't say that (nor does the C99
standard). Declaring or defining a reserved identifier
is undefined behavior, but just using one isn't.
In particular, the fact that the behavior is undefined gives
the compiler permission to treat __func__ as behaving in precisely the
fashion it's required to behave, according to the C99 standard.

No, under the C99 standard a diagnostic must be issued.
No diagnostic, no conformance.

Did you forget that __func__ is predefined in C99 (6.4.2.2)?
Or were you referring to declaring or defining __func__ yourself
(which does cause undefined behavior) as opposed to referring to it?

[...]
 
T

Tim Rentsch

Seebs said:
I'm pretty sure it's intended, but interestingly, it seems as though the only
way that intent is expressed is through the undefined behavior you get if you
try to use the identifier.

I guess the thing is...

Obviously:
int __func__;
is undefined behavior; you're using a reserved identifier.

But if you do
printf("%s\n", __func__);
I can't tell whether this is a constraint violation, in that you're referring
to an undeclared identifier, or plain undefined behavior, because you're using
a reserved identifier.

A syntax error (as explained in my response to Keith). There
is nothing that makes using a reserved identifier be in and
of itself undefined behavior.
... You know, every time I look at this again, my expectation flip-flops. I
conclude that the obvious intent of the standard is that each implementation
shall have a cryptographic-quality source of random numbers, and shall
diagnose this in 50% of all cases, unpredictably.

The most consistent resolution I can see is that it must
be a syntax error unless the implementation documents it
as an extension.
 
T

Tim Rentsch

Keith said:
Tim said:
James said:
On 05/19/2011 05:03 AM, Sorc Chan wrote:
On 18 <<D0>> <<BC>> <<D0>> <<B0>> <<D0>> <<B9>> , 18:08, rouben@shady.(none) (Rouben Rostamian) wrote:
Consider:

#include <stdio.h>
int main(void)
{
printf("entering function %s\n", __func__);
return 0;

} [...]
What would _prevent_ GCC from providing this for C89 code?

Because __func__ in C98 undeclared such as any __ohhelloguys__ thing.

C89 imposes no such requirement. In fact, the main reason why the C89
standard said that a program using __func__ has undefined behavior is so
an implementation can choose to do anything it wishes to do with
__func__.

Except the C89 standard doesn't say that (nor does the C99
standard). Declaring or defining a reserved identifier
is undefined behavior, but just using one isn't.
In particular, the fact that the behavior is undefined gives
the compiler permission to treat __func__ as behaving in precisely the
fashion it's required to behave, according to the C99 standard.

No, under the C99 standard a diagnostic must be issued.
No diagnostic, no conformance.

Did you forget that __func__ is predefined in C99 (6.4.2.2)?

Sorry, what I meant was the C99 diagnostic rules
clearly require a diagnostic if __func__ is not
predefined. Thank you for the clarifying correction.
 
K

Keith Thompson

Tim Rentsch said:
Sorry, what I meant was the C99 diagnostic rules
clearly require a diagnostic if __func__ is not
predefined. Thank you for the clarifying correction.

Hmm. Are you talking about references to __func__ outside a function
definition? (__func__ is implicitly defined immediately after the
opening "{" of any function definition.) Or are you saying that,
in general, a diagnostic is required for a reference to __foo__
if __foo__ is not predefined (for various values of foo)?
 
K

Kenny McCormack

Kiki Thompson said:
Did you forget that __func__ is predefined in C99 (6.4.2.2)?
Or were you referring to declaring or defining __func__ yourself
(which does cause undefined behavior) as opposed to referring to it?

Remind me again: Just exactly how many angels fit on the head of a pin?

--
(This discussion group is about C, ...)

Wrong. It is only OCCASIONALLY a discussion group
about C; mostly, like most "discussion" groups, it is
off-topic Rorsharch [sic] revelations of the childhood
traumas of the participants...
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads

Bug in gcc? 5
man gcc doesn't mention -std=c90 2
What a stupid gcc! 91
Bug in GCC? 10
long double in C89? 7
initialization of local static variable 41
gcc warning and 'basename' 19
Array based Binary Heap in C 19

Members online

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,055
Latest member
SlimSparkKetoACVReview

Latest Threads

Top