My original implementation treated it exactly like a string literal, allowing
it to participate in string concatenation. However, the C9X committee chose to
define it as a predefined indentifier of type 'static char[]' instead. The
revision proposal at http://anubis.dkuug.dk/JTC1/SC22/WG14/www/docs/n611.ps
says that this was to guarantee the relation:
__func__ == __func__
would always hold.
Given the choice, I'd much rather have working string concatenation than this
relation of marginal utility. Anyone have further insight into the committee's
choice here?
Regards,
Graham
>I'd much rather have working string concatenation than this
>relation of marginal utility. Anyone have further insight into the committee's
>choice here?
GCC's authors and maintainers aren't on the C Standard committee, and
the committee didn't really care much how GCC did things when it made
its decisions.
Don't take it personally. In many respects, the C standardization
process was institutionally incompatible with GCC maintenance.
It's still an open question as to how this should be fixed.
That should be 'static const char[]'.
> The revision proposal at
> http://anubis.dkuug.dk/JTC1/SC22/WG14/www/docs/n611.ps
> says that this was to guarantee the relation:
>
> __func__ == __func__
>
> would always hold.
>
> Given the choice, I'd much rather have working string concatenation
> than this relation of marginal utility. Anyone have further insight
> into the committee's choice here?
Check out my original proposal for __func__ at
<http://david.tribble.com/text/c9xfunc.txt>, in which I mention both
GNU C and the '==' operator (though not in the context you state
above). IIRC, I may have discussed the use of '==' in the emails
I sent back and forth to the committee following my proposal; I
don't recall specifically, but I may have suggested, or at least
agreed with, the '==' rule.
It was my desire, which I think was shared by the committee, that
you don't pay for what you don't use, meaning that if a function
does not refer to __func__, the compiler doesn't have to allocate
any space for it.
On the other hand, it was also my (our) desire that if you do use
something, it should be as cheap as possible, meaning that if a
function does refer to __func__, the compiler only needs to provide
a single copy of it. The '==' rule simply forces this to always be
the case.
I'm not sure I follow your argument; could you explain the
implementation difference between a string literal and a
'static const char[]' in gcc?
And what do you mean by "participate in string concatenation"?
If you mean that
strcat("abc", x)
should be legal, then I think you'll get an argument from the
committee (and me) about the inherent const-ness of literals.
If you mean that
strcat(s, __func__)
should be legal, well, it already is (whether or not __func__ is
treated like a literal).
-- David R. Tribble, da...@tribble.com, http://david.tribble.com --
Compilers are still allowed to make only one copy, even if __func__
expands to a string literal. Low-quality compilers might do
otherwise, but they can thwart your efforts in many more ways; I'm not
sure it's worth the effort to try to help them become better.
> I'm not sure I follow your argument; could you explain the
> implementation difference between a string literal and a
> 'static const char[]' in gcc?
>
> And what do you mean by "participate in string concatenation"?
He's talking about string literal concatenation, translation phase 6:
`"foo" "bar"' becomes `"foobar"'. `"In function " __func__' would
become `"In function foo"', in function foo. Since __func__ is not a
string literal, though, we have to do somthing like:
char func[12+sizeof __func__]="In function ";
strcpy(func+12, __func__);
which is less likely to be optimized than duplicate string literals.
paul
In article <3855A00B...@tribble.com>,
David R Tribble <da...@tribble.com> wrote:
>That should be 'static const char[]'.
It probably should be, but there's no const in the revision proposal at
http://anubis.dkuug.dk/JTC1/SC22/WG14/www/docs/n611.ps. Check your original
proposal for the rationale :-).
>> says that this was to guarantee the relation:
>>
>> __func__ == __func__
>>
>> would always hold.
>>
>> Given the choice, I'd much rather have working string concatenation
>> than this relation of marginal utility. Anyone have further insight
>> into the committee's choice here?
...
>It was my desire, which I think was shared by the committee, that
>you don't pay for what you don't use, meaning that if a function
>does not refer to __func__, the compiler doesn't have to allocate
>any space for it.
The same would hold for a string literal; in fact, it's simpler because you
don't have a predefined identifier which has to be optimised away, albeit
trivially.
>On the other hand, it was also my (our) desire that if you do use
>something, it should be as cheap as possible, meaning that if a
>function does refer to __func__, the compiler only needs to provide
>a single copy of it. The '==' rule simply forces this to always be
>the case.
A compiler could already merge duplicate strings under the previous standard.
Besides, there's no rule forcing __FILE__ == __FILE__, and although __func__
isn't a preprocessor macro, I don't see that it should deserve particularly
special treatment here given what's being lost in the process.
>I'm not sure I follow your argument; could you explain the
>implementation difference between a string literal and a
>'static const char[]' in gcc?
You can concatenate string literals by juxtaposition. I'd like to be able to
write stuff like:
#define DB(str) puts(__func__ ": " str)
If __func__ were a string literal, this would work, and there'd be no need to
introduce the notion of a "predefined identifier". Since __func__ is an
identifier though I need to resort to strcat instead, as in your example.
Regards,
Graham
But in practice, __func__ and similar identifiers are most likely to appear
in parameters to printf-like functions. You can let printf do the
concatenation, you don't need to do it during translation.
And even if you are using it as above, it's easy to keep that code from
being part of an inner loop, so the lack of optimization should have
negligible impact.
--
Barry Margolin, bar...@bbnplanet.com
GTE Internetworking, Powered by BBN, Burlington, MA
*** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.
Please DON'T copy followups to me -- I'll assume it wasn't posted to the group.
There are other possibilities. Our delivered code is required to log
error messages using a function that is not printf-like. I currently
create one of the required arguments by declaring:
static const char filefunc[] = __FILE__ ", funcname";
If __func__ were defined to be a string literal, I could replace that
with
static const char filefunc[] = __FILE__ ", " __func__;
but with the definition that's been chosen, the best I could do would
be:
char filefunc[sizeof(__FILE__)+sizeof(__func__)+1];
sprintf(filefunc, "%s, %s", __FILE__, __func__);
which is much more clumsy. I could put it in a macro, I suppose.
> And even if you are using it as above, it's easy to keep that code from
> being part of an inner loop, so the lack of optimization should have
> negligible impact.
If the function itself is inside the loop, that not so easy. I suppose I
could insert:
static char filefunc[sizeof(__FILE__)+sizeof(__func__)+1];
if(!filefunc[0])
sprintf(filefunc, "%s, %s", __FILE__, __func__);
But that's even clumsier. By comparison, the benefits of making it a
const char[] instead of a string literal like __FILE__ seem pretty
negligible.
>Given the choice, I'd much rather have working string concatenation than this
>relation of marginal utility. Anyone have further insight into the committee's
>choice here?
From memory:
(1) Nobody mentioned this as a significant requirement at the point the
proposal was being proposed, or during public comments.
(2) String concatenation occurs at an earlier translation phase (6) than
function identification (7). This would make a string literal difficult
to define correctly. There was no desire to put the effort into twisting
the Standard to solve this for a marginal feature.
--
Clive D.W. Feather | Internet Expert | Work: <cl...@demon.net>
Tel: +44 20 8371 1138 | Demon Internet Ltd. | Home: <cl...@davros.org>
Fax: +44 20 8371 1037 | | Web: <http://www.davros.org>
Written on my laptop; please observe the Reply-To address
I mean, if __func__ is a static const char[], then
couldn't you assign to it? If so, what does that
mean?
For instance, is the following valid?
my_func()
{
__func__[2] = 't';
}
- Dave Rivers -
> couldn't you assign to it?
No.
: I mean, if __func__ is a static const char[], then
^^^^^
: couldn't you assign to it?
No.
--
Mathew Hendry, Programmer, Visual Sciences Ltd.
Work <ma...@vissci.com>, Home <sca...@dial.pipex.com>
IRC/ICQ/Q2/... "Scampi", ICQ 24839718
PGP B3C1 1EBC 2BAE 93F0 54C1 E0E7 5FA3 5988 BBD6 B689
>(2) String concatenation occurs at an earlier translation phase (6) than
>function identification (7). This would make a string literal difficult
>to define correctly. There was no desire to put the effort into twisting
>the Standard to solve this for a marginal feature.
__func__ is merely a convenience; it is not necessary at all.
What you're saying is that the committee
didn't want to make __func__ particularly convenient.
In that case, I'm puzzled as to why they added __func__ at all.
GCC can support both the C9x functionality and the more useful GCC
functionality with __func__, as an extension to C9x.
GCC needs to warn about string concatenation of __func__
only if the -pedantic option is used.
(GCC also has to ensure that __func__ == __func__ yields 1, of course.)
Perhaps Graham Stoney can volunteer to implement it this way,
as he was kind enough to volunteer the original implementation.
(That's what you get for volunteering. :-)
> Thomas David Rivers <riv...@dignus.com> wrote:
>
> : I mean, if __func__ is a static const char[], then
> ^^^^^
> : couldn't you assign to it?
>
> No.
>
Most C implementations just give you a warning
when you assign to `const'... it's typically not an
error... (although, maybe it should be.)
So, what other reasons would there be to not
assign to it...
- Dave R. -
Compiler errors are not what makes illegal constructs illegal. The C
standard specifies what is legal and what is not. If you assign to a
const object, then you are no longer programming in C. You are
programming in a language very much like C, a language your compiler
may accept, a language you may find useful, but not C. So the reason
that you cannot assign to a const object in C:
C99 6.3.2.1p1:
# A modifiable lvalue is an lvalue that ... does not have a
# const-qualified type ....
6.5.2.4p1:
# The operand of the postfix increment or decrement operator ... shall
# be a modifiable lvalue.
6.5.3.1p1:
# The operand of the prefix increment or decrement operator ... shall
# be a modifiable lvalue.
6.5.16p2:
# An assignment operator shall have a modifiable lvalue as its left
# operand.
6.7.3p5:
# If an attempt is made to modify an object defined with a const-
# qualified type through use of an lvalue with non-const-qualified
# type, the behavior is undefined.
paul
All operations that change the value of an object, require that it be
accessed through a modifiable lvalue.
6.3.2.1 p1: "A modifiable lvalue ... does not have a const-qualified
type, ..."
This means that you'll have to use pointer conversions such as
((char*)__func__)[2] to create a modifyiable lvalue referring to a const
object. However, that still won't make it safe:
6.7.3 p5: "If an attempt is made to modify an object defined with a
const-qualified type through use of an lvalue with a non-const-qualified
type, the behavior is undefined."
There's little that the C standard can say that's worse than saying that
something allows undefined behavior. There are real platforms where a
memory segment can be designated to be writable during program
initialization, but to cause a memory fault if you attempt to write to
it at any time after initialization. A conforming implementation of C on
such a platform is allowed, and likely, to put static const objects in
such segments.
But leaving all other considerations aside; if someone chose to
designate something as 'const', that means that it's intended not to
change, which implies that some of the relevant code has been written
with the assumption that it won't be. Changing it is generally a bad
idea, even when it's legal (which it can be, such as when a non-const
object is accessed through a pointer to const).
Clive D.W. Feather wrote:
> From memory:
>
> (1) Nobody mentioned this as a significant requirement at the point
> the proposal was being proposed, or during public comments.
>
> (2) String concatenation occurs at an earlier translation phase (6)
> than function identification (7). This would make a string literal
> difficult to define correctly. There was no desire to put the effort
> into twisting the Standard to solve this for a marginal feature.
Oh, I get it now - Graham was wondering why the following couldn't
have been deemed legal by the committee:
printf("%s", __func__ "()");
Clive's answer (2) answers that question. It also provides the
reason that __func__ was not specified as being a preprocessor
identifier, either.
One question about the gcc implementation, though: What was the
value of __NAME__ when it occurred outside of a function body?
(C99 specifies that __func__ is undefined outside function
definitions.)
> Mathew Hendry wrote:
>
> > Thomas David Rivers <riv...@dignus.com> wrote:
> >
> > : I mean, if __func__ is a static const char[], then
> > ^^^^^
> > : couldn't you assign to it?
> >
> > No.
> >
>
> Most C implementations just give you a warning
> when you assign to `const'... it's typically not an
> error... (although, maybe it should be.)
>
> So, what other reasons would there be to not
> assign to it...
On some C implementations, it will crash when the code is executed.
It might not compile anymore when you upgrade your compiler from version
4.0.1 to version 4.0.2.
If you work at the same company as I do, then your code will not pass the
code review, so you have to rewrite it anyway and serious doubt will be
cast on your competence as a C programmer.
Some C implementations produce code that can run on more than one
operating system, and the code will crash on certain operating systems but
not on others. Worst case: It might not crash on the machine where you
compiled and tested, but on the machine of a customer who paid you tons of
money.
Some C implementations store different strings in the same location if
possible, for example you might find that "ello" == "hello" + 1. If you
change the "o" in "ello" the "o" in "hello" might change as well.
Surprised?
>One question about the gcc implementation, though: What was the
>value of __NAME__ when it occurred outside of a function body?
I assume you mean __FUNCTION__ instead of __NAME__.
The documentation doesn't specify what happens in that case;
but in practice, it's the empty string.
>Clive D.W. Feather wrote:
>> (2) String concatenation occurs at an earlier translation phase (6)
>> than function identification (7). This would make a string literal
>> difficult to define correctly.
>> into twisting the Standard to solve this for a marginal feature.
>Oh, I get it now - Graham was wondering why the following couldn't
>have been deemed legal by the committee:
> printf("%s", __func__ "()");
>Clive's answer (2) answers that question.
It answers the question from the committee's viewpoint perhaps, but
it's not a particularly good answer. There's no problem (in either
theory or practice) with identifying which function body you're in when
you encounter __func__. All (2) says is that the committee's method for
codifying existing practice wasn't compatible with GCC's existing
practice. But the committee's codification method could be fixed
easily if need be, so it's not a strong argument against GCC's practice.
>
> It answers the question from the committee's viewpoint perhaps, but
> it's not a particularly good answer. There's no problem (in either
> theory or practice) with identifying which function body you're in when
> you encounter __func__. All (2) says is that the committee's method for
> codifying existing practice wasn't compatible with GCC's existing
> practice. But the committee's codification method could be fixed
> easily if need be, so it's not a strong argument against GCC's practice.
I think what Clive was trying to point out is that some compilers perform
translation phases 6 (string concatenation) on the whole program before the
start
phase 7 (syntax and semantic analysis). Many compilers have preprocessors
that
run over the whole source before syntax/semantic analysis even starts. A
compiler
must do syntax/semantic analysis in order to know what function it is in.
Therefore,
for some compilers, making __func__ a string literal would be very
difficult.
Ed
> Many compilers have preprocessors that run over the whole source before
> syntax/semantic analysis even starts. A compiler must do
> syntax/semantic analysis in order to know what function it is in.
> Therefore, for some compilers, making __func__ a string literal would
> be very difficult.
Sorry, I still don't see why. It's trivial to do string concatenation
within syntax/semantic analysis: just modify the grammar to allow
multiple string literals where it currently allows just one.
I don't know of any compilers that actually have a separate prepass for
string concatenation; but if there are any, it should be simple to
remove that prepass and do it in the grammar.
>>Clive D.W. Feather wrote:
>>> (2) String concatenation occurs at an earlier translation phase (6)
>>> than function identification (7). This would make a string literal
>>> difficult to define correctly.
>
>[This] answers the question from the committee's viewpoint perhaps, but
>it's not a particularly good answer. There's no problem (in either
>theory or practice) with identifying which function body you're in when
>you encounter __func__. All (2) says is that the committee's method for
>codifying existing practice wasn't compatible with GCC's existing
>practice. But the committee's codification method could be fixed
>easily if need be, so it's not a strong argument against GCC's practice.
Hmm, Clive D.W. Feather says it would be difficult to specify,
but Paul Eggert says it would be easy.
With no disrespect to either, I suggest that the
truth may be somewhere in between.
Was this difficulty of specification worth the benefit?
Well, it's a judgement call. But I think the people who were actually
doing the specification work were probably the ones best placed to
make the call.
--
Fergus Henderson <f...@cs.mu.oz.au> | "I have always known that the pursuit
WWW: <http://www.cs.mu.oz.au/~fjh> | of excellence is a lethal habit"
PGP: finger f...@128.250.37.3 | -- the last words of T. S. Garp.
>Ed Vogel <edward...@compaq.com> writes:
>
>> Many compilers have preprocessors that run over the whole source before
>> syntax/semantic analysis even starts. A compiler must do
>> syntax/semantic analysis in order to know what function it is in.
>> Therefore, for some compilers, making __func__ a string literal would
>> be very difficult.
>
>Sorry, I still don't see why. It's trivial to do string concatenation
>within syntax/semantic analysis: just modify the grammar to allow
>multiple string literals where it currently allows just one.
In fact this seems to be a sensible thing to do anyway. I can't think of
any good reason why the standard separates out phase 6 at all, it
seems a simple syntax driven operation that would be more natural
as part of phase 7, unless there are issues that make it better done
with pp-tokens rather than tokens but I can't think of any offhand.
I suppose historically string literal concatenation was though of as
a preprocessing step but there's no need to think of it that way.
>I don't know of any compilers that actually have a separate prepass for
>string concatenation; but if there are any, it should be simple to
>remove that prepass and do it in the grammar.
I would have thought so.
--
-----------------------------------------
Lawrence Kirby | fr...@genesis.demon.co.uk
Wilts, England | 7073...@compuserve.com
-----------------------------------------
...
>Hmm, Clive D.W. Feather says it would be difficult to specify,
>but Paul Eggert says it would be easy.
>With no disrespect to either, I suggest that the
>truth may be somewhere in between.
It looks very easy. Let me throw this into the pot and watch it get
shot down :-) Lets say references to the string-literal non-terminal
in the grammar relating to translation phase 7 are changed to
string-constant which is defined as
string-constant:
string-constant(opt) string-literal
string-constant(opt) __func__
or perhaps
string-constant:
string-literal string-constant(opt)
__func__ string-constant(opt)
And string-literal remains as
string-literal:
" s-char-sequence(opt) "
L" s-char-sequence(opt) "
...
Since it is now part of the phase 7 grammar I assume __func__ would
have to be made a keyword. The only curiosity I can think of in C99
(which might even be useful) is that L""__func__ would create a wide
string constant.
>Was this difficulty of specification worth the benefit?
>Well, it's a judgement call. But I think the people who were actually
>doing the specification work were probably the ones best placed to
>make the call.
Wording like references to translation phases 6 and 7 would need to
be tidied up but I don't think there would be much else to do. Now
where is the flaw in this argument? :-)
>It looks very easy. Let me throw this into the pot and watch it get
>shot down :-) Lets say references to the string-literal non-terminal
>in the grammar relating to translation phase 7 are changed to
>string-constant which is defined as
>
>string-constant:
> string-constant(opt) string-literal
> string-constant(opt) __func__
>
>or perhaps
>
>string-constant:
> string-literal string-constant(opt)
> __func__ string-constant(opt)
>
>And string-literal remains as
>
>string-literal:
> " s-char-sequence(opt) "
> L" s-char-sequence(opt) "
>
>Since it is now part of the phase 7 grammar I assume __func__ would
>have to be made a keyword. The only curiosity I can think of in C99
>(which might even be useful) is that L""__func__ would create a wide
>string constant.
>
>>Was this difficulty of specification worth the benefit?
>>Well, it's a judgement call. But I think the people who were actually
>>doing the specification work were probably the ones best placed to
>>make the call.
>
>Wording like references to translation phases 6 and 7 would need to
>be tidied up but I don't think there would be much else to do. Now
>where is the flaw in this argument? :-)
Uh ... it's at least a year too late?
--
Peter Curran pcu...@acm.gov (chg gov=>org)
No, I'm saying that the *additional* convenience was marginal enough
that nobody was interested in solving the conceptual problems involved.
Nor can I. Regrettably this doesn't mean that fixing it is trivial. If
someone were to write the complete wording changes required, it could be
put in front of WG14.
Right, *provided* that you are in translation phase 7. If you aren't,
you either have to mix translation phases up or live without certain
features, neither of which are easy enough to be a no-brainer.
>Lawrence Kirby) wrote:
>>Wording like references to translation phases 6 and 7 would need to
>>be tidied up but I don't think there would be much else to do. Now
>>where is the flaw in this argument? :-)
>Uh ... it's at least a year too late?
No, it's in plenty of time for C0x -- assuming there will be a C0x.
Possibly, but that's an awfully big assumption. And if history is
anything to go by, it will probably miss the window for that, too. And
even if it doesn't, the weight of existing practice would make the
change resistable.
If history is anything to go by, there will be a C00 following on the
heels of C99, just like there was a C90 following the C89 standard.
There were also C94 and C95 revisions, too (mostly providing minor
clarifications and ISO enhancements).
As a side note, very few C compilers implement the C95 revision,
even though they almost all implement the C89 revision.
Combining phases 6 and 7 would preclude the ability to write a
separate C lexical analyzer library. (Some of us do this as part
of our job.) Such a library would have to do semantic/grammar
parsing, which requires far more effort than it is worth just to
provide lexer functionality.
I wrote the C lexical analyzer library where I work, which we use
for various C-like preprocessors and small C-like languages (which
have grammars different from C, but which all share the same
lexicon). Handling digraphs and trigraphs properly is difficult
enough, thank you very much, that I wouldn't want to increase my
project timetables just to handle special '__func__' semantics.
Sheesh.
As the originator of the '__func__' proposal, I can say with
certainty that that's not the sort of complication that I had in
mind at all.
>egg...@twinsun.com (Paul Eggert) wrote:
>>No, it's in plenty of time for C0x -- assuming there will be a C0x.
>Possibly, but that's an awfully big assumption. And if history is
>anything to go by, it will probably miss the window for that, too. And
>even if it doesn't, the weight of existing practice would make the
>change resistable.
It's ironic that you'd write ``weight of existing practice'', because
the vast majority of C compiler installations that support __func__
already support string concatenation to it, as this feature is in GCC
2.95 and later (thanks to Ulrich Drepper, Stephen L Moshier, and
Richard Henderson).
Other C compiler writers should take note.
>Combining phases 6 and 7 would preclude the ability to write a
>separate C lexical analyzer library.
No it wouldn't. __func__ is a token. A string is a token.
It's not a problem.
GCC 2.95.2 comes with a C lexical analyzer library,
and it works just fine with __func__.
...
>>Wording like references to translation phases 6 and 7 would need to
>>be tidied up but I don't think there would be much else to do. Now
>>where is the flaw in this argument? :-)
>
>Uh ... it's at least a year too late?
I'm not asking about the feasibility of putting it into C99, I know the
answer to that. I'm asking if anybody can come up with a flaw in the
argument.
>In article <945628...@genesis.demon.co.uk>, Lawrence Kirby
><fr...@genesis.demon.co.uk> writes
>>>Sorry, I still don't see why. It's trivial to do string concatenation
>>>within syntax/semantic analysis: just modify the grammar to allow
>>>multiple string literals where it currently allows just one.
>>
>>In fact this seems to be a sensible thing to do anyway. I can't think of
>>any good reason why the standard separates out phase 6 at all,
>
>Nor can I. Regrettably this doesn't mean that fixing it is trivial.
IMO the most difficult part would be deciding whether to rename phases 7
and 8 to 6 and 7 with the confusion that would cause between different
versions of the standard. I guess we could always adopt the Monty Python
approach:
6. There is no phase 6.
Seriously though I think it is fairly trivial to eliminate phase 6. It
is basically just a part of the process of making __func__ a string constant
that I have already outlined.
>If
>someone were to write the complete wording changes required, it could be
>put in front of WG14.
I might well give that a go.
...
>Combining phases 6 and 7 would preclude the ability to write a
>separate C lexical analyzer library.
Can you explain why?
> (Some of us do this as part
>of our job.) Such a library would have to do semantic/grammar
>parsing, which requires far more effort than it is worth just to
>provide lexer functionality.
The change would not require any knowledge of the grammar to perform
lexical analysis. Even in the current standard string literals are
pp-tokens and the proposal wouldn't change that. The main difference
is that adjacent string literal tokens could still exist after the
preprocessor has finished. I don't think this is a bad thing, indeed
it helps keep things like "\x12" "34" interpreted correctly on
implementations that can generate a textual representation of
preprocessor output. gcc -E appears to do this already.
>I wrote the C lexical analyzer library where I work, which we use
>for various C-like preprocessors and small C-like languages (which
>have grammars different from C, but which all share the same
>lexicon). Handling digraphs and trigraphs properly is difficult
>enough, thank you very much, that I wouldn't want to increase my
>project timetables just to handle special '__func__' semantics.
>Sheesh.
I still don't see why it would cause a problem. The preprocessor
wouldn't handle __func__, it just leaves it as an identifier that
becomes a keyword in phase 7. In phase 7 __func__ creates a multibyte
character sequence in the same way that a string literal does. The
difference is that the sequence of characters produced is derived
from the function name rather than from the character sequence that
composes the string literal token.
>As the originator of the '__func__' proposal, I can say with
>certainty that that's not the sort of complication that I had in
>mind at all.
I certainly wouldn't want to add that sort of complication.
>Peter Curran wrote:
>>
>> egg...@twinsun.com (Paul Eggert) wrote:
>>
>> >pcu...@acm.gov (Peter Curran) writes:
>> >
>> >>Lawrence Kirby) wrote:
>> >>>Wording like references to translation phases 6 and 7 would need to
>> >>>be tidied up but I don't think there would be much else to do. Now
>> >>>where is the flaw in this argument? :-)
>> >
>> >>Uh ... it's at least a year too late?
>> >
>> >No, it's in plenty of time for C0x -- assuming there will be a C0x.
>>
>> Possibly, but that's an awfully big assumption. And if history is
>> anything to go by, it will probably miss the window for that, too. And
>> even if it doesn't, the weight of existing practice would make the
>> change resistable.
>
>If history is anything to go by, there will be a C00 following on the
>heels of C99, just like there was a C90 following the C89 standard.
>There were also C94 and C95 revisions, too (mostly providing minor
>clarifications and ISO enhancements). <snip>
The history to which I was referring was the fact that many
suggestions for revising C89 were made too late in the cycle for that
standard, and many - most, I think - disappeared. Many because their
originators have moved on, many because their originators were not
aware when the windows for suggestions for C9X was open.
As to whether C00 will follow C99 - it seems quite likely to me that
in 10 years C will be of little more than historical interest, and
there will be little enthusiasm for updating the standard. I can't
predict whether that will happen, but it doesn't seem like a
farfetched prediction.
(Our salespeople are already running into resistance from IT managers
to products written in C++, because that is "obsolete" and they don't
want to get their shop involved in it. They would throw us out on our
ear it we were producing code written in C. This may not make sense,
but it is what (parts of) the market is saying.)
>pcu...@acm.gov (Peter Curran) writes:
>
>>egg...@twinsun.com (Paul Eggert) wrote:
>>>No, it's in plenty of time for C0x -- assuming there will be a C0x.
>
>>Possibly, but that's an awfully big assumption. And if history is
>>anything to go by, it will probably miss the window for that, too. And
>>even if it doesn't, the weight of existing practice would make the
>>change resistable.
>
>It's ironic that you'd write ``weight of existing practice'', because
>the vast majority of C compiler installations that support __func__
>already support string concatenation to it, as this feature is in GCC
>2.95 and later (thanks to Ulrich Drepper, Stephen L Moshier, and
>Richard Henderson).
>
>Other C compiler writers should take note.
True now, but presumably not if/when C99 is accepted.
Okay, I've reconsidered the whole "__func__ can act like a string
literal" argument, and I've decided that it is possible to allow
__func__ to behave like a string literal in some circumstances.
printf(__func__ "() called"); // tokens concatenated
Allowing C to handle this would require a change to the grammar,
such that, just as adjacent string literal tokens are concatenated,
so is __func__ when it is adjacent to a string literal. This would
have to occur fairly late in the translation phases.
However, I question the need for allowing __func__ to behave like
this; what problems are being solved that can't be solved using
the existing semantics of __func__?
printf("%s() called", __func__);
// no token concatenation needed
The only argument I've seen put forth is that it will "break"
existing GCC practice. Are there other, more convincing arguments?
There's another angle to this, which appeals to the "spirit" of C,
and that is that allowing an identifier-like entity to behave as
something other than an identifier somehow seems wrong. Currently,
__func__ behaves only as a predefined variable; allowing it to
partake in token concatenation embues it with special properties
beyond those of normal variables.
There's nothing that can't be done, but there are some things which are
far clumsier with the existing semantics. Did you see my message
describing a need to catenate __FILE__ and __func__, before passing them
to a function that did NOT have printf-like argument handling? sprintf()
can certainly do the job, but it is clumsy.
>There's another angle to this, which appeals to the "spirit" of C,
>and that is that allowing an identifier-like entity to behave as
>something other than an identifier somehow seems wrong.
Ah, so now we're talking style, not utility. But C already has several
such entities, including `L', keywords, and many entities in
preprocessor directives (e.g. `if', `defined'). `__func__' is
relatively benign compared to these.
...
>There's another angle to this, which appeals to the "spirit" of C,
>and that is that allowing an identifier-like entity to behave as
>something other than an identifier somehow seems wrong.
It is something that macros do all the time. In what way does this
miss the "spirit of C" that things like __FILE__ don't?
>Currently,
>__func__ behaves only as a predefined variable; allowing it to
>partake in token concatenation embues it with special properties
>beyond those of normal variables.
I don't think it is any more odd than the current definition of __func__.
My definmition makes __func__ a keyword and keywords don't act like
ordinary identifiers.
pcu...@acm.gov (Peter Curran) writes:>egg...@twinsun.com (Paul Eggert) wrote:
>>No, it's in plenty of time for C0x -- assuming there will be a C0x.>Possibly, but that's an awfully big assumption. And if history is
>anything to go by, it will probably miss the window for that, too. And
>even if it doesn't, the weight of existing practice would make the
>change resistable.It's ironic that you'd write ``weight of existing practice'', because
the vast majority of C compiler installations that support __func__
already support string concatenation to it, as this feature is in GCC
2.95 and later (thanks to Ulrich Drepper, Stephen L Moshier, and
Richard Henderson).Other C compiler writers should take note.
Systems/C supports __func__, but not in the GCC style.
The reason being is that the C prologue Systems/C uses keeps
a copy of the function name already, so we simply point to that
at run time... making __func__ pretty straightforward
to implement
in its current semantics.
- Dave Rivers-
-- riv...@dignus.com Work: (919) 676-0847 Get your mainframe (370) `C' compiler at http://www.dignus.com
The example I came across which prompted me to start this thread was how to
use __func__ in a macro which doesn't use printf, but instead calls write(2)
directly. Now I know 'write' isn't an ISO-C standard function but I'd still
like to be able to use __func__. This brought to my attention that,
specification difficulties aside, it's not as useful in its current specified
form as it is in existing language extension practice. What I'd like to be
able to do is stuff like:
#define WRITE(s) write(2, (s), sizeof (s) - 1)
#define STRIFY(n) #n
#define STRN(n) STRIFY(n)
#define DB(m) WRITE(__FILE__ ":" STRN(__LINE__) " in " __func__ ": "(m)"\n")
...
DB("entering");
This happens to work in gcc, but not in the more strict g++, and isn't
portable. In my case I'm actually writing a multithreaded embedded C++ program
where I don't want the overhead of stdio or iostreams, but I would like simple
debug output. Multiple calls to 'write' aren't a good option because the
output won't be thread-safe.
>The only argument I've seen put forth is that it will "break"
>existing GCC practice. Are there other, more convincing arguments?
gcc was raised as an example of how __func__ could be implemented quite simply
as a string literal with the desired properties. The mere fact that gcc does
it this way isn't the compelling point although it should add some weight
given the ideal of standardizing existing practice. The point is that gcc
does it that way for a good reason.
>There's another angle to this, which appeals to the "spirit" of C,
>and that is that allowing an identifier-like entity to behave as
>something other than an identifier somehow seems wrong. Currently,
>__func__ behaves only as a predefined variable; allowing it to
>partake in token concatenation embues it with special properties
>beyond those of normal variables.
But wasn't the concept of predefined variables introduced purely for __func__?
If you treat __func__ more like __FILE__ than like a variable, it's logical
that __func__ should participate in string concatenation just as __FILE__ does.
Regards,
Graham
> In article <38601BC4...@tribble.com>,
> David R Tribble <da...@tribble.com> wrote:
> What I'd like to be
> able to do is stuff like:
>
> #define WRITE(s) write(2, (s), sizeof (s) - 1)
> #define STRIFY(n) #n
> #define STRN(n) STRIFY(n)
> #define DB(m) WRITE(__FILE__ ":" STRN(__LINE__) " in " __func__ ": "(m)"\n")
> ...
> DB("entering");
>
This will not work in lcc-win32. In that implementation, __func__ is a normal
identifier.
Am I doing something against the standard?
The macro above can be rewritten to use strlen instead of sizeof... True, this is
less efficient, but
it is so fast with modern processors, that it doesn't make any difference at all.
#define WRITE(s) write(2,(s), strlen(s)-1)
Why is this so bad?
--
Jacob Navia Logiciels/Informatique
41 rue Maurice Ravel Tel 01 48.23.51.44
93430 Villetaneuse Fax 01 48.23.95.39
France
Would it `break' the C9x standard to implement
__func__ as a string constant (and thus allow
it to participate in string contenation) as an
extension?
I believe there would at least be the `one copy'
issue - would there be anything else?
- Dave Rivers -
Whenever __func__ decays to a pointer, it must decay to the same
pointer, no matter where it occurs within the same function block. So
long as the compiler overlaps identical string literals (or at least the
ones named __func__ ), I think that should work, so long as the compiler
produces a diagnostic whenever code requires __func__ to be a string
literal rather than a character array.
They only thing you're doing wrong is not fully paying attention :-)
This thread started with my complaint that the example I gave _doesn't_ work
because of the unfortunate choice of specification for __func__ given in the
new C99 standard.
>The macro above can be rewritten to use strlen instead of sizeof...
Sure, but it's still relying on string concatenation for the single argument
ultimately passed to strlen/sizeof, so rewriting it to use strlen doesn't[#]
help.
>#define WRITE(s) write(2,(s), strlen(s)-1)
Also, that should be:
#define WRITE(s) write(2,(s), strlen(s))
Regards,
Graham
Footnote:
#: Actually, it does help a little if you're using gcc-2.95.2, where
'sizeof __func__' gives the wrong result due to a compiler bug.
The CodeWarrior implementation of __func__ would be difficult to
rewrite to have the keyword properties you suggest. In our compiler,
we introduce __func__ as an identifier into the scope of the function
when function parsing begins, then when the function has been
completely parsed, we check to see if __func__ was ever referenced.
If so, we then declare the data space for the function name and
associate the identifier with this new data item. It required minimal
compiler changes and satisifies the one pointer rule.
--
Ben Combee <bco...@metrowerks.com> -- x86/Win32/Linux/NetWare CompilerWarrior
Paul Eggert wrote:
> Ah, so now we're talking style, not utility. But C already has
> several such entities, including `L', keywords, and many entities
> in preprocessor directives (e.g. `if', `defined'). `__func__' is
> relatively benign compared to these.
Not exactly. All identifier-like entities in C are either keywords
or identifiers; identifiers specify variables, member, functions,
types, constants, or labels; keywords specify operators or, well,
keywords. The closest C has to an identifier-like entities acting
like literals are enumeration constant names and predefined
preprocessor macro names.
I was merely pointing out that allowing an identifier-like entity
to behave like something other than an identifier or keyword
(outside the realm of preprocessor macros) just doesn't seem C-like.
>The CodeWarrior implementation of __func__ would be difficult to
>rewrite to have the keyword properties you suggest.
I suspect that you're overestimating the amount of work it would take.
You needn't make __func__ a keyword to get the desired behavior.
Just allow concatenation of initialized const char arrays as well as of
strings (with a diagnostic if pedantic). It can't be that big a deal.
You might as well write that code now, so that users won't complain
when they try porting from GCC C99 to CodeWarrior C99.