Topic: Advice: C9X's __func__ on C++
Author: ncm@nospam.cantrip.org (Nathan Myers)
Date: 1999/06/12 Raw View
Ben Combee <bcombee@metrowerks.com> wrote:
>The drafts of C9X (soon to be C0X, it seems) define a predefined
>identifier called __func__ that is visible in any function as a
>static array of char holding the name of the function.
This question raises similar issues about compiler error
messages and debugger output.
The helpful thing to do when producing names for user viewing
is to omit default argument declarations and take advantage of
typedefs and similar aliases. This may add cruft to the compiler
data structures and debug records, but it's easily worthwhile for
the resulting user experience.
For example:
namespace Long_Namespace_Name_A {
class Long_class_name_A { };
}
namespace Long_Namespace_Name_B {
namespace A = ::Long_Namespace_Name_A;
typedef ::Long_class_name_A AA;
template <typename X, typename Y = A::Long_class_name_A>
class B {};
}
namespace My {
namespace B = Long_Namespace_Name_B;
typedef B::B<int> BB;
template <class M>
char const* f(M const&, BB const&) { return __func___; }
}
int main() { std::cout << My::f(My::BB(), My::B::AA()); }
For this (not-very-complicated) example, main could print
::My::f<::Long_Namespace_Name_B::B<int,::A::Long_class_name_A> >(
::Long_Namespace_Name_B::B<int,::A::Long_class_name_A> const&,
::Long_Namespace_Name_A::Long_class_name_A const&))
or
My::f<BB>(BB const&, B::AA const&)
for the same degree of detail in reporting (assuming I haven't made
any gross errors).
For almost all uses, the latter is far more usful than the former.
To me this kind of lookup falls well into the domain of "things
computers are better at than people", and is thus a Good Thing to
automate. If compiler vendors ever begin to compete again, this
would be an easily-advertised, massive competitive advantage.
Again, this issue doesn't affect just __func__, but compiler error
messages and debugger displays.
--
Nathan Myers
ncm@nospam.cantrip.org http://www.cantrip.org/
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: David R Tribble <dtribble@technologist.com>
Date: 1999/06/12 Raw View
Ben Combee wrote:
> The drafts of C9X (soon to be C0X, it seems) define a predefined
> identifier called __func__ that is visible in any function as a
> static array of char holding the name of the function.
>
> I want advice on what the contents of this should be for our C++
> compiler. C9X defines the name to be the simple name of the function,
> so for a function called foo, it would be "foo". With overloading
> and namespaces, just using "foo" seems insufficient for the C++
> version of this, but on the other hand, using a namespace-complete
> form with expanded argument list seems like overkill.
>
> Any advice? What would be most useful for the programmers? Also,
> note that C9X's assert() macro requires the use of __func__ in its
> output.
Speaking as the one who proposed the '__func__' identifier to the
ISO C9X committee, I can tell you what I had in mind for C++.
For C, it suffices to simply use the unadorned function name, since
C doesn't have class scopes or namespaces. For C++, there are a few
reasonable approaches:
1. Use the fully adorned function name, which includes the fully
expanded namespace(s), class prefix(es), template instantiation
parameters, argument prototypes, etc.
Consider this example:
namespace Mine
{
class Foo
{
template <class E>
class Bar
{
template <class T>
int func(int i);
template <class T>
int func(float a, const char *c);
};
};
}
The 'Mine::Foo::Bar<bool>::func<int>(int)' function above would have
a '__func__' value like one of the following:
"Mine::Foo::Bar<bool>::func<int>(int)"
"Mine:Foo:Bar<bool>:func<int>(int)"
"Mine/Foo.Bar<b>.func<i>(i)"
or even perhaps something simpler, just as long as it was readable.
2. Use only the unadorned function name for '__func__', which does
not include any namespace, class, template, or parameter names.
But in addition to '__func__', add the following reserved identifiers:
__namespace__
Contains the fully expanded namespace prefix for a function
or "" for global functions. (E.g., "std::" or perhaps
something shorter such as "std.".)
Example above: "Mine::".
__class__
Contains the fully expanded class prefix for member
functions, or "::" for non-member functions. Includes the
template parameters, if any, with which the class was
instantiated (if the class is a template class).
Example above: "Foo::Bar<bool>::".
__template__
Contains a representation of the template parameters with
which the function was instantiated, otherwise "".
Example above: "<int>".
__args__ (or __parms__)
Contains a representation of the function argument prototype
(such as "(int, const char*)" or "int, const char *", or
perhaps even something simpler like "i,Cc*").
Example above: "(int,const char*)".
(All of these have type 'const char[N]'.)
The advantage of having several predefined identifiers is so that
programmers can pick and choose how much of the function name they
choose to display in debugging statements. The assert() macro
should probably use all of them, though, so that there is no
ambiguity for the user at runtime as to which function caused the
assertion to fail.
3. Use the mangled function name for its '__func__' value.
This guarantees a unique value for each '__func__', but at the
expense of user readability at runtime.
Keep in mind that there need not be any overhead for '__func__' if
it is not used in a function. Note also that '__func__' cannot be
a preprocessor macro, since the preprocessing phase knows nothing
about function names or scopes.
You can read my original proposal at
<http://www.flash.net/~dtribble/text/c9xfunc.txt>; as I recall,
I mentioned a few issues about C++ in it. (Note that the original
name proposed was '__func'.)
-- David R. Tribble, dtribble@technologist.com --
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: David R Tribble <dtribble@technologist.com>
Date: 1999/06/12 Raw View
Ben Combee wrote:
> The drafts of C9X (soon to be C0X, it seems) define a predefined
> identifier called __func__ that is visible in any function as a
> static array of char holding the name of the function.
>
> I want advice on what the contents of this should be for our C++
> compiler. C9X defines the name to be the simple name of the function,
> so for a function called foo, it would be "foo". With overloading
> and namespaces, just using "foo" seems insufficient for the C++
> version of this, but on the other hand, using a namespace-complete
> form with expanded argument list seems like overkill.
>
> Any advice? What would be most useful for the programmers? Also,
> note that C9X's assert() macro requires the use of __func__ in its
> output.
Speaking as the one who proposed the '__func__' identifier to the
ISO C9X committee, I can tell you what I had in mind for C++.
For C, it suffices to simply use the unadorned function name, since
C doesn't have class scopes or namespaces. For C++, there are a few
reasonable approaches:
1. Use the fully adorned function name, which includes the fully
expanded namespace(s), class prefix(es), template instantiation
parameters, argument prototypes, etc.
Consider this example:
namespace Mine
{
class Foo
{
template <class E>
class Bar
{
template <class T>
int func(int i);
template <class T>
int func(float a, const char *c);
};
};
}
The 'Mine::Foo::Bar<bool>::func<int>(int)' function above would have
a '__func__' value like one of the following:
"Mine::Foo::Bar<bool>::func<int>(int)"
"Mine:Foo:Bar<bool>:func<int>(int)"
"Mine/Foo.Bar<b>.func<i>(i)"
or even perhaps something simpler, just as long as it was readable.
2. Use only the unadorned function name for '__func__', which does
not include any namespace, class, template, or parameter names.
But in addition to '__func__', add the following reserved identifiers:
__namespace__
Contains the fully expanded namespace prefix for a function
or "" for global functions. (E.g., "std::" or perhaps
something shorter such as "std.".)
Example above: "Mine::".
__class__
Contains the fully expanded class prefix for member
functions, or "::" for non-member functions. Includes the
template parameters, if any, with which the class was
instantiated (if the class is a template class).
Example above: "Foo::Bar<bool>::".
__template__
Contains a representation of the template parameters with
which the function was instantiated, otherwise "".
Example above: "<int>".
__args__ (or __parms__)
Contains a representation of the function argument prototype
(such as "(int, const char*)" or "int, const char *", or
perhaps even something simpler like "i,Cc*").
Example above: "(int,const char*)".
(All of these have type 'const char[N]'.)
The advantage of having several predefined identifiers is so that
programmers can pick and choose how much of the function name they
choose to display in debugging statements. The assert() macro
should probably use all of them, though, so that there is no
ambiguity for the user at runtime as to which function caused the
assertion to fail.
3. Use the mangled function name for its '__func__' value.
This guarantees a unique value for each '__func__', but at the
expense of user readability at runtime.
Keep in mind that there need not be any overhead for '__func__' if
it is not used in a function. Note also that '__func__' cannot be
a preprocessor macro, since the preprocessing phase knows nothing
about function names or scopes.
You can read my original proposal at
<http://www.flash.net/~dtribble/text/c9xfunc.txt>; as I recall,
I mentioned a few issues about C++ in it. (Note that the original
name proposed was '__func'.)
-- David R. Tribble, dtribble@technologist.com --
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Martin von Loewis <loewis@informatik.hu-berlin.de>
Date: 1999/06/09 Raw View
bcombee@metrowerks.com (Ben Combee) writes:
> I want advice on what the contents of this should be for our C++
> compiler. C9X defines the name to be the simple name of the function,
> so for a function called foo, it would be "foo". With overloading
> and namespaces, just using "foo" seems insufficient for the C++ version
> of this, but on the other hand, using a namespace-complete form with
> expanded argument list seems like overkill.
>
> Any advice?
I'd personally favor a complete name of the function, in some
way. Since it is an area of personal taste, I'd prefer if compiler
vendors define something in their implementations. After a while,
we'll see what kind of tradition has been established, and perhaps
that could then become normative.
Please note that the 'full name' proposal is even more complex than
that, in the presence of template instantiations and methods of local
classes.
Regards,
Martin
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: comeau@panix.com (Greg Comeau)
Date: 1999/06/09 Raw View
In article <slrn7lra47.6l.bcombee@bcombee.metrowerks.com> bcombee@metrowerks.com (Ben Combee) writes:
>The drafts of C9X (soon to be C0X, it seems) define a predefined
>identifier called __func__ that is visible in any function as a
>static array of char holding the name of the function.
>
>I want advice on what the contents of this should be for our C++
>compiler. C9X defines the name to be the simple name of the function,
>so for a function called foo, it would be "foo". With overloading
>and namespaces, just using "foo" seems insufficient for the C++ version
>of this, but on the other hand, using a namespace-complete form with
>expanded argument list seems like overkill.
>
>Any advice? What would be most useful for the programmers? Also,
>note that C9X's assert() macro requires the use of __func__ in its
>output.
It can't be overkill because with anything less it would not be possible
to produce a unique name. For instance, a strong use of it would be
in debugging, instrumentation, etc.
Then again, I think that the C proposal has limitations in C too
(this is not to put it down, I don't know how much more it could do).
For instance, as I recall it, two static functions in different
translation units would have the same name.
As well, I know this gets queasyish, but I'm surprised there was no
wording to the effect that whether it is available or not is unspecified.
That is to say, it could start eating up a chunk of memory in some programs.
Such "machinery" seems to have been a bold move for them.
Surely C++ throws a few curves here too.
- Greg
--
Comeau Computing, 91-34 120th Street, Richmond Hill, NY, 11418-3214
Producers of Comeau C/C++ 4.2.38 -- New Release! We now do Windows too.
Email: comeau@comeaucomputing.com / Voice:718-945-0009 / Fax:718-441-2310
*** WEB: http://www.comeaucomputing.com ***
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: bcombee@metrowerks.com (Ben Combee)
Date: 1999/06/09 Raw View
In article <7jm1mu$d1v$1@panix.com>, Greg Comeau wrote:
> Then again, I think that the C proposal has limitations in C too
> (this is not to put it down, I don't know how much more it could do).
> For instance, as I recall it, two static functions in different
> translation units would have the same name.
Well, with C you can always combine __FILE__ with __func__ to get a
unique identifier (as long as your filenames are unique <GRIN>).
> As well, I know this gets queasyish, but I'm surprised there was no
> wording to the effect that whether it is available or not is unspecified.
> That is to say, it could start eating up a chunk of memory in some programs.
> Such "machinery" seems to have been a bold move for them.
I'm leaning towards using the same short name as C does, but with an
alternate identifier (__func_all__, maybe) that would expand to the
complete name, namespaces, templates, and all. Maybe a
__mangled_func__ too that would map to the compiler-mangled name which
would be more useful for mapping into object files.
--
Ben Combee <bcombee@metrowerks.com> -- x86/Win32/NetWare CompilerWarrior
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: James Kuyper <kuyper@wizard.net>
Date: 1999/06/10 Raw View
Greg Comeau wrote:
....
> Then again, I think that the C proposal has limitations in C too
> (this is not to put it down, I don't know how much more it could do).
> For instance, as I recall it, two static functions in different
> translation units would have the same name.
^^^^^ could
> As well, I know this gets queasyish, but I'm surprised there was no
> wording to the effect that whether it is available or not is unspecified.
It's meant to be guaranteed, not implementation-defined.
> That is to say, it could start eating up a chunk of memory in some programs.
Since __func__ is local to the function, the memory is needed only if
something in the function itself actually refers to __func__, something
which can easily be checked at compile time. This follows from the as-if
rule, but there's also a relevant as-if in the definition of __func__
itself:
"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."
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: "Ken Hagan" <K.Hagan@thermoteknix.co.uk>
Date: 1999/06/10 Raw View
If __func__ is a preprocessor symbol, then I can imagine using
the decorated name for some purposes. That would give us 3 to
choose from -- the immediate name, the fully qualified name, and
the mangled name.
Ben Combee wrote in message ...
>The drafts of C9X (soon to be C0X, it seems) define a predefined
>identifier called __func__ that is visible in any function as a
>static array of char holding the name of the function.
>
>I want advice on what the contents of this should be for our C++
>compiler.
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: James Kuyper <kuyper@wizard.net>
Date: 1999/06/10 Raw View
Ken Hagan wrote:
>
> If __func__ is a preprocessor symbol, then I can imagine using
> the decorated name for some purposes. That would give us 3 to
> choose from -- the immediate name, the fully qualified name, and
> the mangled name.
No - it's a local static const char[]. I think that's why it's lower
case, rather than upper case like (most of?) the other preprocessor
symbols defined by the C standard.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Pete Becker <petebecker@acm.org>
Date: 1999/06/10 Raw View
James Kuyper wrote:
>
> I think that's why it's lower
> case, rather than upper case like (most of?) the other preprocessor
> symbols defined by the C standard.
Also, the preprocessor doesn't know anything about functions, so
technically this can't be done by the preprocessor.
--
Pete Becker
Dinkumware, Ltd.
http://www.dinkumware.com
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Bill Seymour <bsey@pobox.com>
Date: 1999/06/10 Raw View
Ken Hagan wrote:
>
> If __func__ is a preprocessor symbol, ...
>
No, in C9X it's a whole new kind of thing, a "predefined identifier,"
so you can't use it in the preprocessor.
--Bill Seymour
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: comeau@panix.com (Greg Comeau)
Date: 1999/06/10 Raw View
In article <newscache$r0x1df$tpc$1@firewall.thermoteknix.co.uk> "Ken Hagan" <K.Hagan@thermoteknix.co.uk> writes:
>If __func__ is a preprocessor symbol
It can't be. The phases of translation don't allow for it to be one
if the function name is desired. Things like non-preprocessor names (sic)
are not (logically) known till later. Remember, the preprocessor is just
a "dumb text substituter" for the most part, which then "feeds" the other
parts.
- Greg
--
Comeau Computing, 91-34 120th Street, Richmond Hill, NY, 11418-3214
Producers of Comeau C/C++ 4.2.38 -- New Release! We now do Windows too.
Email: comeau@comeaucomputing.com / Voice:718-945-0009 / Fax:718-441-2310
*** WEB: http://www.comeaucomputing.com ***
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: bcombee@metrowerks.com (Ben Combee)
Date: 1999/06/09 Raw View
The drafts of C9X (soon to be C0X, it seems) define a predefined
identifier called __func__ that is visible in any function as a
static array of char holding the name of the function.
I want advice on what the contents of this should be for our C++
compiler. C9X defines the name to be the simple name of the function,
so for a function called foo, it would be "foo". With overloading
and namespaces, just using "foo" seems insufficient for the C++ version
of this, but on the other hand, using a namespace-complete form with
expanded argument list seems like overkill.
Any advice? What would be most useful for the programmers? Also,
note that C9X's assert() macro requires the use of __func__ in its
output.
Thanks!
--
Ben Combee <bcombee@metrowerks.com> -- x86/Win32/NetWare CompilerWarrior
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]