Topic: Adding __func__ to C++


Author: Heinz Huber <Heinz.Huber@elbanet.co.at>
Date: Tue, 19 Dec 2000 10:47:46 GMT
Raw View
OK, I see now.

Thanx,
Heinz

---
[ 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://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]





Author: David R Tribble <david@tribble.com>
Date: Thu, 14 Dec 2000 14:00:10 GMT
Raw View
David R Tribble wrote:
>> The two bar() functions defined in the block-scope local classes
>> could be given unique names by giving their parent block unique
>> names, e.g.:
>>
>>     Info::foo(int)::{1}::Inner::bar(int)   // F1
>>     Info::foo(int)::{2}::Inner::bar(int)   // F2
>>
>> The "{1}" (or something like it) would be unique identification for
>> a local block.

Heinz Huber wrote:
> Interesting idea, but the same problem as with templates remains:
>
> void foo(int i)
> {
>     class Inner
>     {
>         void bar(int j) {}  // F
>     };
> }
>
> The name of F (on call) might be "foo(int i)::Inner::bar(int j)" when
> replacing i and j by the respective parameter values. But again how do
> you split it up?
> __class__ = how ? "foo(int i)::Inner" : "foo(int)::Inner"
> __parms__ = how ? "int j" : "int i::int j"

The distinction between __class__ and __parms__ is much clearer than
between __class__ and __template_args__.  The contents of __parms__
is the parameter type list for the function; any other parameters
or arguments in surrounding functions, classes, or templates don't
appear in this string.

The intent is to be able to combine __func__ (the unadorned function
name) and __parms__ to get something resembling the declaration of
the function.  Thus, given bar() above,

   __func__   = "bar"
   __parms__  = "int"

   printf("%s(%s)", __func__, __parms__) => "bar(int)"

--
David R. Tribble, mailto:david@tribble.com, http://david.tribble.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://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]





Author: David R Tribble <david@tribble.com>
Date: Thu, 14 Dec 2000 18:40:17 GMT
Raw View
Heinz Huber wrote:
> Well, it is no problem as long as you just look at one string. But you
> proposed splitting the name up into parts, one of which were the
> template params. This would not work for the following case (at least
> not in an intuitive way):
>
> template <typename t> class Outer
> {
>     template <typename u> class Inner
>     {
>          void foo(int);   // F
>     };
> };
>
> The complete name would be Outer<t>::Inner::foo(int). But how would
> you split it up?

Perhaps I was too ambitious in my initial proposal, specifying too
many pieces of the function name.  How about a simplified approach:

  __class__

    A string containing the fully qualified prefix for a function,
    including any namespaces (separated by "::"), classes (separated
    by "::"), template instantiation arguments (enclosed within "<"
    and ">"), and any other names required to make the string
    unique within its scope (e.g., local classes defined within
    block scope).  This is empty ("") if the function is not a
    member of any class, is not a template function, and is declared
    at file scope.

  __func__

    A string containing the name of the function, without any
    enclosing class or namespace prefix, but followed by any
    template instantiation arguments (enclosed within "<" and ">").

  __params__

    A string containing the list of parameter types, separated by
    ",".  This is empty ("") if the function is declared with a
    prototype of '()' or '(void)'.


Thus, the following line of code will print out the fully qualified
name for any function:

    std::printf("%s::%s(%s)", __class__, __func__, __params__);

Some examples:

    void f0(void) {...}                      // f0, A

    template <typename C>
    int f1(const C &a) {...}                 // f1

    namespace /*unnamed*/
    {
        class Foo {...};

        void f2()                            // f2, B
        {
            Foo  a;

            f0();
            f1(a);                           // C
        }

        namespace /*unnamed*/
        {
            namespace NS
            {
                template <class T>
                void f3(T &x) {...}          // f3

                template <class T>
                class Outer
                {
                    template <int N>
                    class Inner
                    {
                        void f4(int h)       // f4
                        {
                            {
                                class Local
                                {
                                public:
                                    int f5(T *t, char s[N]) {...}
                                                 // f5
                                };

                                Local  loc;

                                f3(loc);         // D
                                ...
                            }
                        }
                    };
                };

                void f6(int i)               // f6, E
                {
                    Outer<int>::Inner<3>  obj;


                    obj.f4(&i);              // F
                }
            }
        }

The function defined or instantiated above have these predefined
identifier values:

A:
  __class__  = ""
  __func__   = "f0"
  __params__ = ""

B:
  __class__  = "(anon)"
  __func__   = "f2"
  __params__ = ""

C:
  __class__  = ""
  __func__   = "f1<(anon)::Foo>"
  __params__ = "const (anon)::Foo&"

D:
  __class__  =
    "(anon)::(anon)::NS::Outer<int>::Inner<3>::f4(int){1}::Local"
  __func__   =
    "f3<(anon)::(anon)::NS::Outer<int>::Inner<3>::f4(int){1}::Local>"
  __params__ =
    "(anon)::(anon)::NS::Outer<int>::Inner<3>::f4(int){1}::Local&"

E:
  __class__  = "(anon)::(anon)::NS"
  __func__   = "f6"
  __params__ = "int"

F:
  __class__  =
    "(anon)::(anon)::NS::Outer<int>::Inner<3>"
  __func__   =
    "f4"
  __params__ =
    "int"

(Apologies for any errors.)


As a side note, we could allow __class__ to be defined anywhere
within a class or namespace scope, so that the following is valid:

    namespace NS
    {
        const char  mySpace[] = __class__;
        ...
    }

    class Foo
    {
        static const char  myName[] = __class__;
        ...
    };

I'm not sure is this is really a valuable thing to allow, though.

--
David R. Tribble, mailto:david@tribble.com, http://david.tribble.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://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]





Author: David R Tribble <david@tribble.com>
Date: Fri, 15 Dec 2000 16:37:44 GMT
Raw View
David R Tribble wrote:
> Perhaps I was too ambitious in my initial proposal, specifying too
> many pieces of the function name.  How about a simplified approach:
>
>   __class__
>      [...]
>   __func__
>      [...]
>   __params__
>      [...]

Actually, the simplest proposal is to provide only two predefined
identifiers for functions:

  __func__

  Contains the unadorned name of the function, suitably translated
  into the execution character set.

  (The semantics of this identifier force compatibility with ISO
  C99.  Thus for any function named 'foo', the string has the value
  "foo", regardless of namespace and class prefixes, template
  instantiation arguments, or parameter types.)

  __fullfunc__

  Contains a unique name for the function, distinguishable from any
  other function in the program.  The actual form of the string is
  implementation-defined.

  (This allows the string to contain a fully qualified function
  name, including all namespace and class prefixes, block scope
  specifiers, template instantiation arguments, and parameter types,
  in any form deemed suitably unique by the compiler implementor.
  This allows the string to contain, among other possible formats,
  the mangled linker symbol name for the symbol, if the vendor so
  desires.  Or it could be as simple as a linker address, which
  assumes that the programmer has some way of correlating it to
  the function it uniquely references.)

The advantage of this approach is that it is the easiest for
implementors to provide.

--
David R. Tribble, mailto:david@tribble.com, http://david.tribble.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://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]





Author: David R Tribble <david@tribble.com>
Date: Fri, 15 Dec 2000 17:06:09 GMT
Raw View
David R Tribble wrote:
>> To cover all the bases in C++, though, we would have to deal
>> with function names that:
>>  - have namespace prefixes
>>  - have class prefixes (i.e., are member functions)
>>  - have template instantiation parameter types/values
>>  - have overloaded parameter types (i.e., different signatures)

Heinz Huber wrote:
> template <typename t> class Outer
> {
>     template <typename u> class Inner
>     {
>          void foo(int);   // A
>     };
> };
>
> The complete name would be Outer<t>::Inner::foo(int). But how would
> you split it up?
> __class__ = how ? "Outer<t>::Inner<u>" : "Outer<t>::Inner" :
> "Outer::Inner"
> __template_parms__ = how ? "" : "<u>" : "<t>::<u>"

> void foo(int i)
> {
>     class Inner
>     {
>         void bar(int j) {}  // B
>     };
> }
>
> The name of F (on call) might be "foo(int i)::Inner::bar(int j)" when
> replacing i and j by the respective parameter values. But again how do
> you split it up?
> __class__ = how ? "foo(int i)::Inner" : "foo(int)::Inner"
> __parms__ = how ? "int j" : "int i::int j"


My proposal is based on the idea that, given the completely qualified
name of a function, it decomposes naturally into six parts.  Reading
a fully qualified function name from left to right, they are:

 - Any namespace prefixes, including nested and unnamed namespaces.

 - Any class prefixes, including nested class names and template
   instantiation arguments for enclosing template classes.

 - The enclosing function block scope, for member functions of
   local classes declared within functions or statement blocks.

 - The unadorned name of the function, which also includes names
   for constructors, destructors, and operators.

 - The template instantiation arguments that apply directly to the
   function, if it is a template function.

 - The list of parameter types, where array and function types are
   replaced by their equivalent pointer types.  Parameter names are
   ignored, as are any cv-qualifiers that directly modify the
   parameters.  Member functions (probably should) have an extra
   first parameter representing the implicit 'this' pointer (which
   could be named "this" for simplicity).

For simplicity, the first three prefixes (namespace, class, and
function block scope) can combined into a single "scope" prefix.

The key point to realize is that you don't combine all the template
arguments, for instance, into a single subname, but apply them in
the appropriate place in the appropriate subnames.


Thus, for your example A above, you have:

  full name: Outer<t>::Inner<u>::foo(int)
             ^                   ^  ^^
  scope:     Outer<t>::Inner<u>
  func:      foo
  template:  (empty)
  params:    int

For your example B above, you have something like:

  full name: foo(int)::Inner::bar(foo(int)::Inner*,int)
             ^                ^  ^^
  scope:     foo(int)::Inner
  func:      bar
  template:  (empty)
  params:    this,int

A more complicated example is:

    namespace MyLib
    {
        template <class T>
        class Foo
        {
            template <class U, int N>
            int bar(const T *const o, int);   // C
        };
    }

  full name: MyLib::Foo<T>::bar<U,N>(MyLib::Foo<T>*,const T*,int)
             ^              ^  ^     ^
  scope:     MyLib::Foo<T>
  func:      bar
  template:  <U,N>
  params:    this,const T*,int

(Note that the template parameters 'T' and 'U' in the strings above
would be replaced with actual instantiation names, such as 'int' or
'MySpace::MyClass<float>'.)


Given the six naming parts described above, and after combining the
first three, we get these four predefined naming identifiers:

  __scope__
  __func__
  __template__
  __params__


(If this is too complicated, see my other post in this thread, which
describes having only two predefined identifiers.)

--
David R. Tribble, mailto:david@tribble.com, http://david.tribble.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://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]





Author: Heinz Huber <Heinz.Huber@elbanet.co.at>
Date: Tue, 12 Dec 2000 14:39:33 GMT
Raw View

David R Tribble wrote:
>
> David R Tribble wrote:
> >> To cover all the bases in C++, though, we would have to deal
> >> with function names that:
> >>  - have namespace prefixes
> >>  - have class prefixes (i.e., are member functions)
> >>  - have template instantiation parameter types/values
> >>  - have overloaded parameter types (i.e., different signatures)
>
> Heinz Huber wrote:
> > Playing devil's advocate:
> > What about nested classes (perhaps even in a template class)
>
> Nested classes are not a problem:
>
>     class Outer
>     {
>         class Inner
>         {
>             void foo(int);   // F
>         };
>     };
>
> The name of F is:
>
>     Outer::Inner::foo(int)
>
> Any template instantiation arguments are added accordingly, and
> comprise the fully qualified class name prefix for the member
> function.

Well, it is no problem as long as you just look at one string. But you
proposed splitting the name up into parts, one of which were the
template params. This would not work for the following case (at least
not in an intuitive way):

template <typename t> class Outer
{
    template <typename u> class Inner
    {
         void foo(int);   // F
    };
};

The complete name would be Outer<t>::Inner::foo(int). But how would you
split it up?
__class__ = how ? "Outer<t>::Inner<u>" : "Outer<t>::Inner" :
"Outer::Inner"
__template_parms__ = how ? "" : "<u>" : "<t>::<u>"


> > and functions of inner (?) structs (meaning structs in a function)?
>
> Yes, I overlooked that.
>
>     int Info::foo(int n)
>     {
>         if (n > 0)
>         {
>             class Inner                   // C1
>             {
>             public:
>                 int  bar(int i) { ... }   // F1
>             };
>
>             return Inner::bar(n);
>         }
>         else
>         {
>             class Inner                   // C2
>             {
>             public:
>                 int  bar(int i) { ... }   // F2
>             };
>
>             return Inner::bar(-n);
>         }
>     }
>
> The two bar() functions defined in the block-scope local classes
> could be given unique names by giving their parent block unique
> names, e.g.:
>
>     Info::foo(int)::{1}::Inner::bar(int)   // F1
>     Info::foo(int)::{2}::Inner::bar(int)   // F2
>
> The "{1}" (or something like it) would be unique identification for
> a local block.

Interesting idea, but the same problem as with templates remains:

void foo(int i)
{
    class Inner
    {
        void bar(int j) {}  // F
    };
}

The name of F (on call) might be "foo(int i)::Inner::bar(int j)" when
replacing i and j by the respective parameter values. But again how do
you split it up?
__class__ = how ? "foo(int i)::Inner" : "foo(int)::Inner"
__parms__ = how ? "int j" : "int i::int j"

As an aside, it might also be interesting to get the return value.

Regards,
Heinz

---
[ 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://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]





Author: David R Tribble <david@tribble.com>
Date: Tue, 12 Dec 2000 14:44:27 GMT
Raw View
>>  2  Since the __func__ that lives in C99 has this property
>>     (that is, it is a valid C identifer) there may be a growing
>>     body of code (admittedly C99, not C89 or C++) that depends
>>     on this property. Are we still trying to be as close as
>>     possible but no closer?

David R Tribble <david@tribble.com> wrote...
>> It was my intention that __func__ be no more than the unadorned
>> function name.  This is perfectly reasonable in C, but some think
>> this might not be the case in C++.

Ken Hagan wrote:
> That would mean that __func__ was not unique. This might break
> "non-debug" uses of __func__ in code originally written for C99.
> Would it be better to keep __func__ as the fully qualified name
> and create "__name__" alongside __class__ and __args__ and so on?

Possibly.  Or perhaps the opposite: let __func__ be the unadorned
function name and __name__ be the fully qualified name.  Either
way, you're going to break some code somewhere.

--
David R. Tribble, mailto:david@tribble.com, http://david.tribble.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://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]





Author: David R Tribble <david@tribble.com>
Date: Tue, 12 Dec 2000 14:44:19 GMT
Raw View
David R Tribble <david@tribble.com> wrote...
>> I think Gene meant that there could be macros that would use the
>> predefined names (__func__, et al) to form *strings* containing
>> appropriate names.  If the macros are limited to string token
>> pasting, I don't think there will be any problems.
>>
>> I don't expect (nor did I intend) that the predefined identifiers
>> would be used to somehow construct actual identifiers.

Ken Hagan wrote:
> Ah. I thought that *was* Gene's point, and it meant there were
> legitimate uses for __func__ and its friends outside debugging
> traces.
>
> People use __FILE__ and __LINE__ to build anonymous variables.
> Could things like __class__ be used to create similar animals
> with wider scope, and would they be useful? (Does the order of
> preprocessing make this impossible?)

Since __func__ (and __class__ et al) is not a preprocessing symbol,
I'd say that such things would be more difficult.  You can use it
as an argument to strchr() and strstr(), though, to pick apart
substrings at runtime.  This might be useful for things like loading
dynamic libraries on demand.

--
David R. Tribble, mailto:david@tribble.com, http://david.tribble.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://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]





Author: James Kuyper <kuyper@wizard.net>
Date: Tue, 12 Dec 2000 14:46:34 GMT
Raw View
Ken Hagan wrote:
...
> People use __FILE__ and __LINE__ to build anonymous variables.
> Could things like __class__ be used to create similar animals
> with wider scope, and would they be useful? (Does the order of
> preprocessing make this impossible?)]

Yes.

---
[ 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://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]





Author: David R Tribble <david@tribble.com>
Date: Thu, 7 Dec 2000 17:58:45 GMT
Raw View
David R Tribble <david@tribble.com> wrote...
>> One solution is to simply include all of this naming information
>> in the contents of '__func__'.

Ken Hagan wrote:
> I'm happy with this solution. I can't think of any use for
> __func__ except debugging, and in that case I'd tolerate
> the verbosity and would certainly want to avoid ambiguity.
> I wouldn't want a mangled name. (You don't mention these,
> but other people have mentioned them in this context in
> the past.)

The biggest problem with using mangled names is that there is no
single standard for name mangling, so the output of a given program
would vary widely from system to system.  This could be a real pain,
such as if you have your customers generate and send you tracing log
files which you then apply text searching tools to; such tools would
have to be rewritten for every platform you support.

On the other hand, using mangled names has the advantage of yielding
names that directly correspond to binary object (linker) symbols.

But I still think there ought to be a simple, efficient way to
retrieve the unadorned function name.


> I'd also be happy if __func__ was allowed to be an empty
> string (with a non-unique address) in release builds.

The requirements of __func__ are such that if you don't use it in
a given function, the compiler is not obligated to generate code
or data for it in that function.  You don't pay for what you don't
need.

So presumably, you #ifdef the debugging/tracing code so that it
doesn't get compiled into production binaries.  (This is a practice
I disagree with, BTW.)


> I can't think of a good use for all these other strings that
> you've suggested. I expect that's my lack of imagination.

It allows function tracing/debugging code to be as verbose as the
programmer chooses, without requiring a lot of programming effort
(such as picking apart substrings).  For instance, a given application
might not need anything more uniquely identifying that the unadorned
function name in its trace logs.  Other applications might require
the fully qualified function names and source files.  Such variance
is the reason for giving the programmer a certain amount of
flexibility, so he can choose what he needs.

--
David R. Tribble, mailto:david@tribble.com, http://david.tribble.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://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]





Author: David R Tribble <david@tribble.com>
Date: Thu, 7 Dec 2000 18:08:09 GMT
Raw View
David R Tribble <david@tribble.com> wrote:
>> To cover all the bases in C++, though, we would have to deal
>> with function names that:
>>  - have namespace prefixes
>>  - have class prefixes (i.e., are member functions)
>>  - have template instantiation parameter types/values
>>  - have overloaded parameter types (i.e., different signatures)

Jim Hyslop wrote:
> One more issue to cover - how would we handle typedefs? For example,
> would the name inside an instantiation of:
>
>    std::map<std::string, std::string>
>
> print out as "std::map<std::string, std::string>" or as
> "std::map<std::basic_string<class charT, class char_traits<charT>,
>   class allocator<charT> [etc. etc. etc.]" (or whatever all the
> typedefs expand to).

The latter.  Since typedefs can vary from one source file to another,
the name of a given typedef in one object module of a program could
very likely be identical to a typedef in another object module in
the program but which has an entirely different underlying type.

    // one.hpp

    typedef int  ItemRef;


    // two.hpp

    class Item { ... };
    typedef Item *  ItemRef;

The instantiations of the following template function, while
instantiated using identical typedef names, are in fact different
functions, and thus should have different (fully qualified) names.

    template <class T>
    void foo(T &ref)
    { ... }

    ItemRef  r;
    ... foo(r) ...    // foo<ItemRef>(r), which
                      // depends on which 'ItemRef' is used

--
David R. Tribble, mailto:david@tribble.com, http://david.tribble.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://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]





Author: David R Tribble <david@tribble.com>
Date: Fri, 8 Dec 2000 14:56:47 GMT
Raw View
Barry Margolin <barmar@genuity.net> writes:
>>| That's why I also prefer his other suggestion, "anonymous
>>| namespace".  A programmer-defined namespace name can't have
>>| whitespace.

Gabriel Dos_Reis <gdosreis@sophia.inria.fr> wrote
>> I would prefer a C++ identifier -- probably the unique name invented
>> for that anonymous namespace, or something less verbose that at any
>> rate a C++ identifier.

Mike Dimmick wrote:
> I'm afraid that the unique name would probably end up looking like
> line-noise - much the same for any anonymous enumeration (or class
> or union, which are not standard, but supported by many compilers).
>
> How about:
>
>    anonymous(file.cpp)::
>
> since of course there is only one unnamed namespace per translation
> unit.  The parentheses are (I feel) a good indication.

This is good idea.  I would shorten it a bit:

    {file.cpp}::

Unfortunately, filenames have no standard format, and can actually
be quite complex.  And even then, they might not produce a unique
enough name on some systems.

Consider IBM S/390 MVS filenames, which look something like this:

    //'SYS.INCLUDE.C89.H(STDIO)'

> However, we are dealing with standards, so it would probably best
> to define it as 'an implementation defined name, which shall be
> documented by the implementation'.  It would then be a QoI issue.

Perhaps.  Something like "(anon)" might be useful, but it doesn't
indicate *which* anonymous namespace the function lives in.  But
is this a problem worth solving?


> Anonymous enumerations might be tricky; they don't really have any
> form of identification at all.

And thus cannot be used as function parameter types, I believe.
So I don't think this is a problem.

--
David R. Tribble, mailto:david@tribble.com, http://david.tribble.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://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]





Author: David R Tribble <david@tribble.com>
Date: Fri, 8 Dec 2000 14:58:09 GMT
Raw View
David R Tribble  <david@tribble.com> wrote:
>+   __namespace__
>+
>+     A static const char array initialized to the fully qualified
>+     namespace prefix (which may include nested namespace
>+     identifiers) of the containing function, followed by "::".
>+     This is empty ("") if the function is not defined within a
>+     namespace scope.  This is "static::" if the function is defined
>+     in an anonymous namespace.

Phil Edwards wrote:
> I'm with you right up until the last sentence.  The word "static"
> can easily cause a lot of confusion among even experienced C++
> programmers who are learning about anonymous namespaces.  I thought
> the idea was that using 'static' to mean file-local scope and
> storage was deprecated, since we now have those anonymous spaces.
>
> I rather like gcc's way of reporting such things in error messages
> and demangled names:
>
>     ... (anonymous namespace)::foo
>
> So I would suggest "anonymous::" rather than "static::", or maybe
> even "anonymous namespace" since the presence of a space would call
> attention to the fact that it wasn't done by the programmer.

The problem with using any name (e.g. "anonymous") other than a
keyword (e.g., "static") is that the programmer can define a
namespace using that name:

    namespace anonymous { ... }

That's why I chose "static", since it's impossible to define a
namespace (or any other kind of identifier) of that name.

However, I see your point about potential confusion.  The solution
is to realize that any combination of characters that do not form
a proper identifier could be used to indicate "anonymous namespace".

Some possibilities, off the top of my head:

    "static::"
    "(anonymous)::"
    "anonymous namespace::"
    "%none::"
    "{}::"
    "-::"
    ":::"

--
David R. Tribble, mailto:david@tribble.com, http://david.tribble.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://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]





Author: David R Tribble <david@tribble.com>
Date: Fri, 8 Dec 2000 14:58:51 GMT
Raw View
David R Tribble wrote:
>> To cover all the bases in C++, though, we would have to deal
>> with function names that:
>>  - have namespace prefixes
>>  - have class prefixes (i.e., are member functions)
>>  - have template instantiation parameter types/values
>>  - have overloaded parameter types (i.e., different signatures)

Heinz Huber wrote:
> Playing devil's advocate:
> What about nested classes (perhaps even in a template class)

Nested classes are not a problem:

    class Outer
    {
        class Inner
        {
            void foo(int);   // F
        };
    };

The name of F is:

    Outer::Inner::foo(int)

Any template instantiation arguments are added accordingly, and
comprise the fully qualified class name prefix for the member
function.


> and functions of inner (?) structs (meaning structs in a function)?

Yes, I overlooked that.

    int Info::foo(int n)
    {
        if (n > 0)
        {
            class Inner                   // C1
            {
            public:
                int  bar(int i) { ... }   // F1
            };

            return Inner::bar(n);
        }
        else
        {
            class Inner                   // C2
            {
            public:
                int  bar(int i) { ... }   // F2
            };

            return Inner::bar(-n);
        }
    }

The two bar() functions defined in the block-scope local classes
could be given unique names by giving their parent block unique
names, e.g.:

    Info::foo(int)::{1}::Inner::bar(int)   // F1
    Info::foo(int)::{2}::Inner::bar(int)   // F2

The "{1}" (or something like it) would be unique identification for
a local block.

--
David R. Tribble, mailto:david@tribble.com, http://david.tribble.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://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]





Author: James.Kanze@dresdner-bank.com
Date: Fri, 8 Dec 2000 18:23:44 GMT
Raw View
In article <xaj3dg0m3jz.fsf@korrigan.inria.fr>,
  Gabriel Dos_Reis <gdosreis@sophia.inria.fr> wrote:
> pedwards@dmapub.dma.org (Phil Edwards) writes:

> | David R Tribble  <david@tribble.com> wrote:

> | + And I feel compelled (being on the West side of the Atlantic) that
> | + the ISO C and C++ standards are written in American English, and
> | + that the syntax and library of both originated in the U.S. and
thus
> | + carry a lot of Americanisms.

> | I'm on the same side of the Atlantic as you.  :-) I think the only
> | really obvious Americanism that I can recall in the c++ standard
> | (apart from trivial issues of spelling) is the expansion of POD.
> | Other than that it seemed to be fairly neutral writing.

> Like `specialization' or `behavior'?

He said "except for trivial issues of spelling".  The only thing
"American" I can see with those two words is the spelling.  And in the
case of spelling, you don't really have a choice.  There is no neutral
spelling for many words -- it is either American or British.

An interesting aside: although most Europeans learned Britsh English
in school, on all international projects I've been on, the "official"
usage has been American spelling.  Mainly because that is the default
for most spelling checkers.  (And in at least one case, the decision
was made by a British person.)

--
James Kanze                               mailto:kanze@gabi-soft.de
Conseils en informatique orient   e objet/
                  Beratung in objekt orientierter Datenverarbeitung
Ziegelh   ttenweg 17a, 60598 Frankfurt, Germany Tel. +49(069)63198627


Sent via Deja.com http://www.deja.com/
Before you buy.

---
[ 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://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]





Author: James Kuyper <kuyper@wizard.net>
Date: Fri, 8 Dec 2000 19:20:26 GMT
Raw View
Gabriel Dos_Reis wrote:
>
> pedwards@dmapub.dma.org (Phil Edwards) writes:
...
> | I'm on the same side of the Atlantic as you.  :-)  I think the only really
> | obvious Americanism that I can recall in the c++ standard (apart from
> | trivial issues of spelling) is the expansion of POD.  Other than that it
> | seemed to be fairly neutral writing.
>
> Like `specialization' or `behavior'?

Exactly: "trivial issues of spelling"

---
[ 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://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]





Author: Martin von Loewis <loewis@informatik.hu-berlin.de>
Date: Sun, 10 Dec 2000 00:11:27 GMT
Raw View
Barry Margolin <barmar@genuity.net> writes:

> That's why I also prefer his other suggestion, "anonymous namespace".  A
> programmer-defined namespace name can't have whitespace.

BTW, the official term is "unnamed namespace".

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://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]





Author: "Ken Hagan" <K.Hagan@thermoteknix.co.uk>
Date: Mon, 11 Dec 2000 16:00:10 GMT
Raw View
"David R Tribble" <david@tribble.com> wrote...
>
> I think Gene meant that there could be macros that would use the
> predefined names (__func__, et al) to form *strings* containing
> appropriate names.  If the macros are limited to string token
> pasting, I don't think there will be any problems.
>
> I don't expect (nor did I intend) that the predefined identifiers
> would be used to somehow construct actual identifiers.

Ah. I thought that *was* Gene's point, and it meant there were
legitimate uses for __func__ and its friends outside debugging
traces.

People use __FILE__ and __LINE__ to build anonymous variables.
Could things like __class__ be used to create similar animals
with wider scope, and would they be useful? (Does the order of
preprocessing make this impossible?)

If you are just thinking about forming strings, then I would
take the position that the precise contents of __func__ can be
anything or nothing, since it is just a quality of implementation
issue, like the class names you get from type_info.

> >  2  Since the __func__ that lives in C99 has this property
> >     (that is, it is a valid C identifer) there may be a growing
> >     body of code (admittedly C99, not C89 or C++) that depends
> >     on this property. Are we still trying to be as close as
> >     possible but no closer?
>
> It was my intention that __func__ be no more than the unadorned
> function name.  This is perfectly reasonable in C, but some think
> this might not be the case in C++.

That would mean that __func__ was not unique. This might break
"non-debug" uses of __func__ in code originally written for C99.
Would it be better to keep __func__ as the fully qualified name
and create "__name__" alongside __class__ and __args__ and so on?

> Some of us, including me, don't like the idea of using the mangled
> name.  For one thing, we would prefer names that resemble the
> names used in the source code.

Agreed. C implementations mangle names too, of course, even if it
is only to prefix an underscore or two. Since __func__ doesn't
honour that (?), there is no existing practice to encourage C++
to provide the mangled name.

---
[ 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://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]





Author: Jim Hyslop <jim.hyslop@leitch.com>
Date: 2000/12/06
Raw View
In article <xajd7f6q572.fsf@korrigan.inria.fr>,
  Gabriel Dos_Reis <gdosreis@sophia.inria.fr> wrote:
[snip discussion: how to name an anyonymous namespace]
>
> I would prefer a C++ identifier -- probably the unique name invented
> for that anonymous namespace,  or something less verbose that at any
> rate a C++ identifier.
I'm not so sure about that - the unique name would likely be rather
unintelligible. Since (I presume) the main purpose of the __func__ and
related keywords is a debugging aid, I would want something more easily
comprehended.

--
Jim
This message was posted using plain text only.  Any hyperlinks you may
see were added by other parties without my permission.
I do not endorse any products or services that may be hyperlinked to
this message.


Sent via Deja.com http://www.deja.com/
Before you buy.

---
[ 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://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]






Author: "Mike Dimmick" <mike@dimmick.demon.co.uk>
Date: 2000/12/06
Raw View
"Gabriel Dos_Reis" <gdosreis@sophia.inria.fr> wrote in message
news:xajd7f6q572.fsf@korrigan.inria.fr...
> Barry Margolin <barmar@genuity.net> writes:

[...]

> | That's why I also prefer his other suggestion, "anonymous namespace".  A
> | programmer-defined namespace name can't have whitespace.
>
> I would prefer a C++ identifier -- probably the unique name invented
> for that anonymous namespace, or something less verbose that at any
> rate a C++ identifier.

I'm afraid that the unique name would probably end up looking like
line-noise - much the same for any anonymous enumeration (or class or union,
which are not standard, but supported by many compilers).

How about:

anonymous(file.cpp)::

since of course there is only one unnamed namespace per translation unit.
The parentheses are (I feel) a good indication.

However, we are dealing with standards, so it would probably best to define
it as 'an implementation defined name, which shall be documented by the
implementation'.  It would then be a QoI issue.

Anonymous enumerations might be tricky; they don't really have any form of
identification at all.  An anonymous /class/ (where I mean class in the
sense of the standard, section 9) must have an object of that type declared
at the point of definition (the extension I was discussing earlier deals
with anonymous classes with no declarator-id).

--
Mike Dimmick


---
[ 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://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]






Author: Barry Margolin <barmar@genuity.net>
Date: 2000/12/06
Raw View
In article <976048796.16165.0.nnrp-08.d4e5bde1@news.demon.co.uk>,
Mike Dimmick <mike@dimmick.demon.co.uk> wrote:
>However, we are dealing with standards, so it would probably best to define
>it as 'an implementation defined name, which shall be documented by the
>implementation'.  It would then be a QoI issue.

But perhaps it should require (or at least recommend) that the name be of a
form that cannot conflict with a user-defined namespace.

--
Barry Margolin, barmar@genuity.net
Genuity, 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.

---
[ 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://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]






Author: "Ken Hagan" <K.Hagan@thermoteknix.co.uk>
Date: 2000/12/06
Raw View
I wrote:
>
> I can't think of any use for __func__ except debugging

"Gene Bushuyev" <gbush@deja.com> wrote...
>
> It can be useful in some automatically generated code, when
> using __func__, __class__, etc. macros can be used to produce
> specific names.

Fair enough. Actually, this is quite a severe constraint.

 1  This gives us quite a significant restriction on the text
    that these "macros" can expand to. They can't contain
    spaces or "::", for starters.

 2  Since the __func__ that lives in C99 has this property
    (that is, it is a valid C identifer) there may be a growing
    body of code (admittedly C99, not C89 or C++) that depends
    on this property. Are we still trying to be as close as
    possible but no closer?

 3  On some implementations, it rules out the possibility of
    __func__ being the mangled name. (MSVC uses "?" and "@"
    in its mangling scheme, precisely because these can't
    appear in C++ identifiers.) That's another possibility
    that I've seen suggested in the past.

---
[ 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://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]






Author: Christopher Eltschka <celtschk@physik.tu-muenchen.de>
Date: 2000/12/07
Raw View
Mike Dimmick wrote:
>
> "Gabriel Dos_Reis" <gdosreis@sophia.inria.fr> wrote in message
> news:xajd7f6q572.fsf@korrigan.inria.fr...
> > Barry Margolin <barmar@genuity.net> writes:
>
> [...]
>
> > | That's why I also prefer his other suggestion, "anonymous namespace".  A
> > | programmer-defined namespace name can't have whitespace.
> >
> > I would prefer a C++ identifier -- probably the unique name invented
> > for that anonymous namespace, or something less verbose that at any
> > rate a C++ identifier.
>
> I'm afraid that the unique name would probably end up looking like
> line-noise - much the same for any anonymous enumeration (or class or union,
> which are not standard, but supported by many compilers).
>
> How about:
>
> anonymous(file.cpp)::
>
> since of course there is only one unnamed namespace per translation unit.

I disagree:

namespace // anon1
{
  int i;
}

namespace foo
{
  namespace // anon2
  {
    int i;
  }
}

Now (anon)::i and foo::(anon)::i are two different variables.

> The parentheses are (I feel) a good indication.

What about putting the "anonymous" into the brackets, too?

(anonymous file.cpp)::

>
> However, we are dealing with standards, so it would probably best to define
> it as 'an implementation defined name, which shall be documented by the
> implementation'.  It would then be a QoI issue.
>
> Anonymous enumerations might be tricky; they don't really have any form of
> identification at all.

But how can anonymous enumerations appear in function names?
BTW, an anonymous enumeration could be identified by it's first
enumerator
(I don't think empty enumerations are allowed, and empty anonymous
enumerations would be quite useless ;-)).

[...]

---
[ 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://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]






Author: David R Tribble <david@tribble.com>
Date: 2000/12/07
Raw View
David R Tribble  <david@tribble.com> wrote:
>+   __template_parms__
>+   __parms__

Phil Edwards wrote:
> "parms" strikes me as a distinct Americanism; how about "params" if
> "parameters" is too long?

Well, C and C++ already have 'va_arg' and C99 has '__VA_ARGS__',
so it probably be more consistent to use something like '__args__'.

And I feel compelled (being on the West side of the Atlantic) that
the ISO C and C++ standards are written in American English, and
that the syntax and library of both originated in the U.S. and thus
carry a lot of Americanisms.

However, as I understand it, "argument" is the term for a supplied
value in an actual function call or template instantiation, whereas
"parameter" is the placeholder in the declaration/definition of
the function or template.  That's why I chose "parm", since it
appears to be more correct.  At least for function parameter type
names; it might be better to use "__args__" for template
instantiation types/values.

My proposed names were meant to be initial suggestions, and so
I'm not married to any particular spelling.  "__params__" is as
good a name as any (so far).

(It's related to the old question of how you pronounce "char".)

--
David R. Tribble, mailto:david@tribble.com, http://david.tribble.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://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]






Author: pedwards@dmapub.dma.org (Phil Edwards)
Date: 2000/12/07
Raw View
David R Tribble  <david@tribble.com> wrote:
+
+ And I feel compelled (being on the West side of the Atlantic) that
+ the ISO C and C++ standards are written in American English, and
+ that the syntax and library of both originated in the U.S. and thus
+ carry a lot of Americanisms.

I'm on the same side of the Atlantic as you.  :-)  I think the only really
obvious Americanism that I can recall in the c++ standard (apart from
trivial issues of spelling) is the expansion of POD.  Other than that it
seemed to be fairly neutral writing.


+ However, as I understand it, "argument" is the term for a supplied
+ value in an actual function call or template instantiation, whereas
+ "parameter" is the placeholder in the declaration/definition of
+ the function or template.  That's why I chose "parm", since it
+ appears to be more correct.  At least for function parameter type
+ names; it might be better to use "__args__" for template
+ instantiation types/values.

I think I agree with you there.


+ (It's related to the old question of how you pronounce "char".)

Simple; it's like the first syllable of "char*".


Phil

--
pedwards at disaster dot jaj dot com  |  pme at sources dot redhat dot com
devphil at several other less interesting addresses in various dot domains
The gods do not protect fools.  Fools are protected by more capable fools.

---
[ 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://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]






Author: Gabriel Dos_Reis <gdosreis@sophia.inria.fr>
Date: 2000/12/07
Raw View
pedwards@dmapub.dma.org (Phil Edwards) writes:

| David R Tribble  <david@tribble.com> wrote:
| +
| + And I feel compelled (being on the West side of the Atlantic) that
| + the ISO C and C++ standards are written in American English, and
| + that the syntax and library of both originated in the U.S. and thus
| + carry a lot of Americanisms.
|
| I'm on the same side of the Atlantic as you.  :-)  I think the only really
| obvious Americanism that I can recall in the c++ standard (apart from
| trivial issues of spelling) is the expansion of POD.  Other than that it
| seemed to be fairly neutral writing.

Like `specialization' or `behavior'?

--
Gabriel Dos Reis, dosreis@cmla.ens-cachan.fr

---
[ 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://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]






Author: David R Tribble <david@tribble.com>
Date: 2000/12/07
Raw View
>> I can't think of any use for __func__ except debugging

Gene Bushuyev <gbush@deja.com> wrote...
>> It can be useful in some automatically generated code, when
>> using __func__, __class__, etc. macros can be used to produce
>> specific names.

Ken Hagan wrote:
> Fair enough. Actually, this is quite a severe constraint.
>
>  1  This gives us quite a significant restriction on the text
>     that these "macros" can expand to. They can't contain
>     spaces or "::", for starters.

Bear in mind that __func__ is an identifier (i.e., the name of
a static const char[] object), not a macro.

I think Gene meant that there could be macros that would use the
predefined names (__func__, et al) to form *strings* containing
appropriate names.  If the macros are limited to string token
pasting, I don't think there will be any problems.

I don't expect (nor did I intend) that the predefined identifiers
would be used to somehow construct actual identifiers.


>  2  Since the __func__ that lives in C99 has this property
>     (that is, it is a valid C identifer) there may be a growing
>     body of code (admittedly C99, not C89 or C++) that depends
>     on this property. Are we still trying to be as close as
>     possible but no closer?

It was my intention that __func__ be no more than the unadorned
function name.  This is perfectly reasonable in C, but some think
this might not be the case in C++.


>  3  On some implementations, it rules out the possibility of
>     __func__ being the mangled name. (MSVC uses "?" and "@"
>     in its mangling scheme, precisely because these can't
>     appear in C++ identifiers.) That's another possibility
>     that I've seen suggested in the past.

Again, __func__ is a constant static string, not a token sequence
forming an identifier.  So it could contain any permutation of
characters.

Some of us, including me, don't like the idea of using the mangled
name.  For one thing, we would prefer names that resemble the
names used in the source code.

--
David R. Tribble, mailto:david@tribble.com, http://david.tribble.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://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]






Author: "Ken Hagan" <K.Hagan@thermoteknix.co.uk>
Date: 2000/12/04
Raw View
"David R Tribble" <david@tribble.com> wrote...
>
> One solution is to simply include all of this naming information
> in the contents of '__func__'.

I'm happy with this solution. I can't think of any use for
__func__ except debugging, and in that case I'd tolerate
the verbosity and would certainly want to avoid ambiguity.
I wouldn't want a mangled name. (You don't mention these,
but other people have mentioned them in this context in
the past.)

I'd also be happy if __func__ was allowed to be an empty
string (with a non-unique address) in release builds.

For release code, I already have a function that returns its
own return address. This requires some porting effort and it
is harder to interpret, but it gives me a way of identifying
"where it went wrong" in my log file that is both efficient
and unique. That's what I want for logging events on customer
machines. I wouldn't replace it with __func__ no matter how
we defined it.

I can't think of a good use for all these other strings that
you've suggested. I expect that's my lack of imagination.


---
[ 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://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]






Author: Jim Hyslop <jim.hyslop@leitch.com>
Date: 2000/12/04
Raw View
In article <3A27ED19.88F6AD6A@tribble.com>,
  David R Tribble <david@tribble.com> wrote:
> Now that the latest revision of ISO C (ISO/IEC 9899:1999, a.k.a. C99)
> has the predefined identifier '__func__', it would be a good time to
> discuss how such a feature could be added to C++.
>
[snip]
> in C++.  To cover all the bases in C++, though, we would have to deal
> with function names that:
>  - have namespace prefixes
>  - have class prefixes (i.e., are member functions)
>  - have template instantiation parameter types/values
>  - have overloaded parameter types (i.e., different signatures)
One more issue to cover - how would we handle typedefs? For example,
would the name inside an instantiation of:

std::map<std::string, std::string>

print out as "std::map<std::string, std::string>" or as

"std::map<std::basic_string<class charT, class char_traits<charT>, class
allocator<charT> [etc. etc. etc.]" (or whatever all the typedefs expand
to).

--
Jim
This message was posted using plain text only.  Any hyperlinks you may
see were added by other parties without my permission.
I do not endorse any products or services that may be hyperlinked to
this message.


Sent via Deja.com http://www.deja.com/
Before you buy.

---
[ 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://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]






Author: Gabriel Dos_Reis <gdosreis@sophia.inria.fr>
Date: 2000/12/04
Raw View
pedwards@dmapub.dma.org (Phil Edwards) writes:

[...]

| So I would suggest "anonymous::" rather than "static::",

But then it is hard to distinguish from the following:

 namespace anonymous
 {
  void foo(int);
 }

--
Gabriel Dos Reis, dosreis@cmla.ens-cachan.fr

---
[ 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://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]






Author: Barry Margolin <barmar@genuity.net>
Date: 2000/12/05
Raw View
In article <xajd7f86o1x.fsf@korrigan.inria.fr>,
Gabriel Dos_Reis  <gdosreis@sophia.inria.fr> wrote:
>pedwards@dmapub.dma.org (Phil Edwards) writes:
>
>[...]
>
>| So I would suggest "anonymous::" rather than "static::",
>
>But then it is hard to distinguish from the following:
>
> namespace anonymous
> {
>  void foo(int);
> }

That's why I also prefer his other suggestion, "anonymous namespace".  A
programmer-defined namespace name can't have whitespace.

The original proposer probably used "static" for a similar reason: since
it's a reserved word, it can't be used as a namespace name.

--
Barry Margolin, barmar@genuity.net
Genuity, 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.

---
[ 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://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]






Author: Heinz Huber <Heinz.Huber@elbanet.co.at>
Date: 2000/12/05
Raw View

David R Tribble wrote:
>
> Now that the latest revision of ISO C (ISO/IEC 9899:1999, a.k.a. C99)
> has the predefined identifier '__func__', it would be a good time to
> discuss how such a feature could be added to C++.
>
> In C99, '__func__' is defined only within function bodies, and acts
> like a const char array that has been initialized to the name of the
> containing function.  For example, the following code:
>
>     void foo(int n)
>     {
>         printf("%s\n", __func__);
>     }
>
> acts as if the following definition were inserted after the '{':
>
>         static const char  __func__[] = "foo";
>
> and produces the following output:
>
>     foo
>
> (The issue of converting from the translation character set to the
> execution character set is mentioned in the std.  The feature is
> also worded such that if '__func__' is never mentioned in a given
> function, the compiler is free to omit any generated code for it.
> The '__func__' identifier is also used in the suggested definition
> of the 'assert()' macro.)
>
> This works well for C, since function names are much simpler than
> in C++.  To cover all the bases in C++, though, we would have to deal
> with function names that:
>  - have namespace prefixes
>  - have class prefixes (i.e., are member functions)
>  - have template instantiation parameter types/values
>  - have overloaded parameter types (i.e., different signatures)
>
> One solution is to simply include all of this naming information
> in the contents of '__func__'.
>
> Another solution is to invent a few more predefined identifiers to
> deal with all of these [partial] names:
>
>   __namespace__
>
>     A static const char array initialized to the fully qualified
>     namespace prefix (which may include nested namespace
>     identifiers) of the containing function, followed by "::".
>     This is empty ("") if the function is not defined within a
>     namespace scope.  This is "static::" if the function is defined
>     in an anonymous namespace.
>
>   __class__
>
>     A static const char array initialized to the fully qualified
>     class prefix (which may include nested class identifiers) of
>     the containing function, followed by the template parameters
>     used to instantiate the class (if any).  The template portion
>     of the array is the type names and values of the template
>     parameters used to instantiate the class, preceded by "<" and
>     followed by ">", which is empty ("") if the class is not a
>     template class.  The entire array is empty ("") if the function
>     has no class prefix (i.e., if the function is not a class
>     member function).
>
>   __template_parms__
>
>     A static const char array initialized to the type names and
>     values of the template parameters used to instantiate the
>     containing function, preceded by "<" and followed by ">".
>     This is empty ("") if the function is not a template function.
>
>   __parms__
>
>     A static const char array initialized to the type names of all
>     of the containing function's parameters (which may include a
>     trailing ellipsis '...').  This is empty ("") if the function
>     has a prototype of '()' or '(void)'.
>
>   __func__
>
>     A static const char array initialized to the unadorned name of
>     the containing function.  [This is the same as the C99
>     semantics for '__func__'.]

[snip]

Playing devil's advocate:
What about nested classes (perhaps even in a template class) and
functions of inner (?) structs (meaning structs in a function)?

Regards,
Heinz

---
[ 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://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]






Author: "Gene Bushuyev" <gbush@deja.com>
Date: 2000/12/05
Raw View
"Ken Hagan" <K.Hagan@thermoteknix.co.uk> wrote in message
news:newscache$0uu15g$21m$1@firewall.thermoteknix.co.uk...
> "David R Tribble" <david@tribble.com> wrote...
> >
> > One solution is to simply include all of this naming information
> > in the contents of '__func__'.
>
> I'm happy with this solution. I can't think of any use for
> __func__ except debugging, and in that case I'd tolerate

It can be useful in some automatically generated code, when using __func__,
__class__, etc. macros can be used to produce specific names.

-------------------------
Gene Bushuyev
"Funny noises are not funny" (Bart Simpsons)


---
[ 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://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]






Author: Gabriel Dos_Reis <gdosreis@sophia.inria.fr>
Date: 2000/12/05
Raw View
Barry Margolin <barmar@genuity.net> writes:

| In article <xajd7f86o1x.fsf@korrigan.inria.fr>,
| Gabriel Dos_Reis  <gdosreis@sophia.inria.fr> wrote:
| >pedwards@dmapub.dma.org (Phil Edwards) writes:
| >
| >[...]
| >
| >| So I would suggest "anonymous::" rather than "static::",
| >
| >But then it is hard to distinguish from the following:
| >
| > namespace anonymous
| > {
| >  void foo(int);
| > }
|
| That's why I also prefer his other suggestion, "anonymous namespace".  A
| programmer-defined namespace name can't have whitespace.

I would prefer a C++ identifier -- probably the unique name invented
for that anonymous namespace, or something less verbose that at any
rate a C++ identifier.

--
Gabriel Dos Reis, dosreis@cmla.ens-cachan.fr

---
[ 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://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]






Author: David R Tribble <david@tribble.com>
Date: 2000/12/02
Raw View
Now that the latest revision of ISO C (ISO/IEC 9899:1999, a.k.a. C99)
has the predefined identifier '__func__', it would be a good time to
discuss how such a feature could be added to C++.

In C99, '__func__' is defined only within function bodies, and acts
like a const char array that has been initialized to the name of the
containing function.  For example, the following code:

    void foo(int n)
    {
        printf("%s\n", __func__);
    }

acts as if the following definition were inserted after the '{':

        static const char  __func__[] = "foo";

and produces the following output:

    foo

(The issue of converting from the translation character set to the
execution character set is mentioned in the std.  The feature is
also worded such that if '__func__' is never mentioned in a given
function, the compiler is free to omit any generated code for it.
The '__func__' identifier is also used in the suggested definition
of the 'assert()' macro.)

This works well for C, since function names are much simpler than
in C++.  To cover all the bases in C++, though, we would have to deal
with function names that:
 - have namespace prefixes
 - have class prefixes (i.e., are member functions)
 - have template instantiation parameter types/values
 - have overloaded parameter types (i.e., different signatures)

One solution is to simply include all of this naming information
in the contents of '__func__'.

Another solution is to invent a few more predefined identifiers to
deal with all of these [partial] names:

  __namespace__

    A static const char array initialized to the fully qualified
    namespace prefix (which may include nested namespace
    identifiers) of the containing function, followed by "::".
    This is empty ("") if the function is not defined within a
    namespace scope.  This is "static::" if the function is defined
    in an anonymous namespace.

  __class__

    A static const char array initialized to the fully qualified
    class prefix (which may include nested class identifiers) of
    the containing function, followed by the template parameters
    used to instantiate the class (if any).  The template portion
    of the array is the type names and values of the template
    parameters used to instantiate the class, preceded by "<" and
    followed by ">", which is empty ("") if the class is not a
    template class.  The entire array is empty ("") if the function
    has no class prefix (i.e., if the function is not a class
    member function).

  __template_parms__

    A static const char array initialized to the type names and
    values of the template parameters used to instantiate the
    containing function, preceded by "<" and followed by ">".
    This is empty ("") if the function is not a template function.

  __parms__

    A static const char array initialized to the type names of all
    of the containing function's parameters (which may include a
    trailing ellipsis '...').  This is empty ("") if the function
    has a prototype of '()' or '(void)'.

  __func__

    A static const char array initialized to the unadorned name of
    the containing function.  [This is the same as the C99
    semantics for '__func__'.]

Example I:

    namespace MyLib
    {
        namespace MathLib
        {
            template <class T>
            class Util
            {
            public:
                class Pkg
                {
                public:
                    template <int N>
                    int foo(const T *p, int h);       // A
                };
            };

            ... Util<Info>::Pkg::foo<3>(&in, 17) ...  // B
        }
    }

The fully qualified name of the function that is instantiated
at [B] is:

    MyLib::MathLib::Util<Info>::foo<3>(const Info*, int)

This yields the following predefined identifiers within the body
of the function:

    __namespace__       = "MyLib::MathLib::"
    __class__           = "Util<Info>"
    __template_parms__  = "<3>"
    __func__            = "foo"
    __parms__           = "const Info*,int"

These string values can be printed:

    std::printf("%s%s::%s%s(%s)\n",
        __namespace__, __class__, __func__,
        __template_parms__, __parms__);

so as to produce the output:

    MyLib::MathLib::Util<Info>::foo<3>(const Info*,int)

Example II:
Given a simpler function without all the adornments:

    void bar(int h)                          // C
    {
        std::printf(... as shown above ...);
    }

the predefined identifiers have simpler values:

    __namespace__       = ""
    __class__           = ""
    __template_parms__  = ""
    __func__            = "foo"
    __parms__           = "int"

and thus the output of the printf() is much simpler:

    ::bar(int)

Providing separate pieces of the fully qualified function name in
separate predefined identifiers allows the programmer to choose
what parts of the function name he wishes to output (i.e., he may
not want the complete, fully adorned function name).

Comments?

--
David R. Tribble, mailto:david@tribble.com, http://david.tribble.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://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]






Author: pedwards@dmapub.dma.org (Phil Edwards)
Date: 2000/12/04
Raw View
I'll let somebody else describe GNU's __PRETTY_FUNCTION__, since we've
all probably seen it by now.  I'll just add...


David R Tribble  <david@tribble.com> wrote:
+
+   __namespace__
+
+     A static const char array initialized to the fully qualified
+     namespace prefix (which may include nested namespace
+     identifiers) of the containing function, followed by "::".
+     This is empty ("") if the function is not defined within a
+     namespace scope.  This is "static::" if the function is defined
+     in an anonymous namespace.

I'm with you right up until the last sentence.  The word "static" can easily
cause a lot of confusion among even experienced C++ programmers who are
learning about anonymous namespaces.  I thought the idea was that using
'static' to mean file-local scope and storage was deprecated, since we
now have those anonymous spaces.

I rather like gcc's way of reporting such things in error messages and
demangled names:

    % cat t.cc

    namespace
    {
        int foo;
    }

    % g++ -c t.cc
    % nm t.o | c++filt -s gnu-new-abi | grep foo
    0000000000000000 B (anonymous namespace)::foo
    %

So I would suggest "anonymous::" rather than "static::", or maybe even
"anonymous namespace" since the presence of a space would call attention
to the fact that it wasn't done by the programmer.


+   __template_parms__
+   __parms__

"parms" strikes me as a distinct Americanism; how about "params" if
"parameters" is too long?


+ Providing separate pieces of the fully qualified function name in
+ separate predefined identifiers allows the programmer to choose
+ what parts of the function name he wishes to output (i.e., he may
+ not want the complete, fully adorned function name).

We're definitely in agreement there.


Luck++;
Phil

--
pedwards at disaster dot jaj dot com  |  pme at sources dot redhat dot com
devphil at several other less interesting addresses in various dot domains
The gods do not protect fools.  Fools are protected by more capable fools.

---
[ 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://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]