Topic: typeid().name syntax


Author: stephen.clamage@sun.com (Steve Clamage)
Date: 1998/11/25
Raw View
AllanW@my-dejanews.com writes:


>In article <734du3$4t9$1@engnews2.Eng.Sun.COM>,
>  clamage@Eng.Sun.COM (Steve Clamage) wrote:
>> AllanW@my-dejanews.com writes:

>> >  18.5.1 Class type_info

>> >      bool before(const type_info& rhs) const;

>> >  5 Effects: Compares the current object with rhs.
>> >  6 Returns: true if *this precedes rhs in the implementation's
>> >    collation order.

>> >Some have suggested that before() could return a different
>> >sorted order of types in different runs. But the last two
>> >words have a strong implication: We use SOME collating
>> >sequence. It doesn't specifically state that the collating
>> >sequence is applied to the class name, but this is strongly
>> >implied.

>> I don't see that implication at all. If the typeinfo objects
>> are unique per type in the final program, the simplest
>> implemenation of "before" would be to compare the addresses.
>> (You as a C++ programmer can't portably compare addresses of
>> unrelated objects, but the implementation can do whatever
>> it wants under the covers.)

>We often speak of sorting; for instance, a list of salespersons
>can be sorted by commission or by salary. But AFAIK we reserve
>the word "collate" to mean "sort by some text field" and the
>text is usually (but not always) the name.

Do you have a reference for that assumption? It is not borne
out by my dictionary. None of the definitions I find speak
of "sorting by some text field." OTOH, one definition of
collate is "to place in numerical or logical order."

>But I couldn't find anything that says what happens when before()
>is used on two classes with the same name, and I did look.

A requirement on the typeid operator is that two type_info
objects compare equal if and only if the types referred to are
the same. Different types could have the same name (the same name
in the program, or the same value returned by typeid.name()) yet
must compare unequal. See sections 5.2.8 and 18.5.1 of the standard.


--
Steve Clamage, stephen.clamage@sun.com

      [ Send an empty e-mail to c++-help@netlab.cs.rpi.edu for info ]
      [ about comp.lang.c++.moderated. First time posters: do this! ]


[ 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 <david.tribble@noSPAM.central.beasys.com>
Date: 1998/11/26
Raw View
James Kuyper <kuyper@wizard.net> wrote:
>> reasonable implementation will
>> make name() return something understandable, but there's no guarantee
>> that it will be appropriate for insertion in a type declaration.

Siemel Naran wrote:
> Forget about classes inside functions (local classes) and classes in
> unnamed namespaces.  For all other classes, the requirements that the
> string returned by type_info::name() be unique AND human readable
> AND compilable are easily reconciled:
>
> namespace Silly { class X { }; }
> int main()                              // [corrected -drt]
> {
>     cout << typeid(int).name() << " i;\n"
>         << typeid(Silly::X).name() << " x;\n";
> }
>
> This program should output
>    int i;
>    Silly::X x;

This is apparently what most people expect.  But don't forget that
the resulting string is the type name translated from the source
character set into the execution character set.  These two sets
are identical in most implementations, but there may be some
subtle side effects in the translation on other systems.  Consider
a compiler that accepts Unicode source files but uses an 8-bit
'char' type at runtime.

Of course the description of typeid.name() does not mention this,
either.

-- 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: AllanW@my-dejanews.com
Date: 1998/11/24
Raw View
In article <734du3$4t9$1@engnews2.Eng.Sun.COM>,
  clamage@Eng.Sun.COM (Steve Clamage) wrote:
> AllanW@my-dejanews.com writes:
>
> >  18.5.1 Class type_info
>
> >      bool before(const type_info& rhs) const;
>
> >  5 Effects: Compares the current object with rhs.
> >  6 Returns: true if *this precedes rhs in the implementation's
> >    collation order.
>
> >Some have suggested that before() could return a different
> >sorted order of types in different runs. But the last two
> >words have a strong implication: We use SOME collating
> >sequence. It doesn't specifically state that the collating
> >sequence is applied to the class name, but this is strongly
> >implied.
>
> I don't see that implication at all. If the typeinfo objects
> are unique per type in the final program, the simplest
> implemenation of "before" would be to compare the addresses.
> (You as a C++ programmer can't portably compare addresses of
> unrelated objects, but the implementation can do whatever
> it wants under the covers.)

We often speak of sorting; for instance, a list of salespersons
can be sorted by commission or by salary. But AFAIK we reserve
the word "collate" to mean "sort by some text field" and the
text is usually (but not always) the name.

I suppose you could speak of collating by textual-equivalent of
the address in hex or decimal.  In this case internal address
123456 would sort before internal address 2000, unless you
left-pad with 0's to make them always the same length, in which
case it's equivalent to sorting by binary address and hardly
deserving of the term "collate".

> If the implementation compares the names, it would need to solve
> the problems brought up here before: having unique names for each
> unique type, and the same name for the same types.

Mr. Clamage, usually you know a lot more about the C++ spec than
I do. (In black and white type on Usenet, this may look like
sarcasm. It isn't meant as such. Please accept this as a
compliment; I am frequently amazed at how much you know.)

But I couldn't find anything that says what happens when before()
is used on two classes with the same name, and I did look.
Couldn't they compare equal? For instance, if typeid(A).name() is
"A" and typeid(::A).name() is also "A", then
    typeid(A).before(typeid(::A))  is false and
    typeid(::A).before(typeid(A))  is also false
because A doesn't come before A "in the implementation's
collation order." Or did I miss something?

--
AllanW@my-dejanews.com is a "Spam Magnet" -- never read.
Please reply in USENET only, sorry.

-----------== Posted via Deja News, The Discussion Network ==----------
http://www.dejanews.com/       Search, Read, Discuss, or Start Your Own

      [ Send an empty e-mail to c++-help@netlab.cs.rpi.edu for info ]
      [ about comp.lang.c++.moderated. First time posters: do this! ]


[ 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: 1998/11/25
Raw View
Biju Thomas wrote:
>
> In article <72sepd$5mj$1@nnrp1.dejanews.com>,
>   AllanW@my-dejanews.com wrote:
...
> > Some have suggested that before() could return a different
> > sorted order of types in different runs.
>
> I believe that is not possible, as the collation order of classes doesn't
> change between runs. It is hard-wired in the object code.

It doesn't have to be. Each type_info object could be created for the
first time by the first typeid() done on that type. The collating
sequence could be in the order in which they were created.
I'm not saying this is likely, merely that I believe it is permitted.


      [ Send an empty e-mail to c++-help@netlab.cs.rpi.edu for info ]
      [ about comp.lang.c++.moderated. First time posters: do this! ]
---
[ 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: clamage@Eng.Sun.COM (Steve Clamage)
Date: 1998/11/21
Raw View
AllanW@my-dejanews.com writes:

>  18.5.1 Class type_info

>      bool before(const type_info& rhs) const;

>  5 Effects: Compares the current object with rhs.
>  6 Returns: true if *this precedes rhs in the implementation's
>    collation order.

>Some have suggested that before() could return a different
>sorted order of types in different runs. But the last two
>words have a strong implication: We use SOME collating
>sequence. It doesn't specifically state that the collating
>sequence is applied to the class name, but this is strongly
>implied.

I don't see that implication at all. If the typeinfo objects
are unique per type in the final program, the simplest
implemenation of "before" would be to compare the addresses.
(You as a C++ programmer can't portably compare addresses of
unrelated objects, but the implementation can do whatever
it wants under the covers.)

If the implementation compares the names, it would need to solve
the problems brought up here before: having unique names for each
unique type, and the same name for the same types.

--
Steve Clamage, stephen.clamage@sun.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: sbnaran@fermi.ceg.uiuc.edu (Siemel Naran)
Date: 1998/11/20
Raw View
On 18 Nov 1998 21:35:53 GMT, James Kuyper <kuyper@wizard.net> wrote:

>I don't see any use of typeid().name() in that code. I would guess that
>your code assumes that typeid(int).name() to return "int". Would it do
>what you need it to do if typeid(int).name() instead returned "C int" or
>"integer" or "0x11234"?

If typeid(int).name() points to "0x11234" then the program will print
"typedef 0x11234 int;" which is hardly useful.  The member function
Typedef::operator<<(T) makes the call to typeid(T).name().


>That's what I mean by not being useful. A reasonable implementation will
>make name() return something understandable, but there's no guarantee
>that it will be appropriate for insertion in a type declaration.

Forget about classes inside functions (local classes) and classes in
unnamed namespaces.  For all other classes, the requirements that the
string returned by type_info::name() be unique AND human readable
AND compilable are easily reconciled:

namespace Silly { class X { }; }
int main(){cout<<typeid(int).name() " i;\n" <<typeid(Silly::X)<< " x;\n";}

This program should output
   int i;
   Silly::X x;


>That gives me an idea: if you want to standardize name()'s return value,
>require it to be a string that could be used to declare an object of the
>same type. Combined with a requirement that two objects of the same
>most-derived type must have identical name()s, that would remove a lot
>of the ambiguity. It would also make the value useful in automatic code
>generation.

Fine.  Ideally, for polymorphic types, the typeid stuff should be stored
in the vtable and there should be only one vtable per class.  I think
this should be not too hard for the compiler designers to achieve :).


>There's probably something seriously wrong with this idea.

Should there be a space between successive ">"?  Eg, which should we see
   std::auto_ptr<std::vector<int,std::allocator<int>>>;
   std::auto_ptr<std::vector<int,std::allocator<int> > >;
Both versions are unique and human readable.  But only the second is
compilable.

This is not that serious.  Can't think of anything else.

--
----------------------------------
Siemel B. Naran (sbnaran@uiuc.edu)
----------------------------------
---
[ 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: Valentin Bonnard <bonnardv@pratique.fr>
Date: 1998/11/20
Raw View
AllanW@my-dejanews.com wrote:

> Does anyone know who proposed that typeid should have a name()
> function? Is that person active on this newsgroup? If so, please
> tell us what the original purpose was. Does name(), as it is
> currently specified, meet that purpose?

FWIW:

name() is there since at least january 94, with an unspecified
return value (not even implementation defined).

I haven't found any proposals about it.

--

Valentin Bonnard                mailto:bonnardv@pratique.fr
info about C++/a propos du C++: http://pages.pratique.fr/~bonnardv/


      [ Send an empty e-mail to c++-help@netlab.cs.rpi.edu for info ]
      [ about comp.lang.c++.moderated. First time posters: do this! ]
---
[ 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: AllanW@my-dejanews.com
Date: 1998/11/20
Raw View
In article <3650309F.776C00A5@physik.tu-muenchen.de>,
  Christopher Eltschka <celtschk@physik.tu-muenchen.de> wrote:
> Siemel Naran wrote:
>
> [...]
>
> > >What I wonder, now, is exactly what value name() has. Why is
> > >it in the standard at all? If I knew it's purpose, my
> > >expectations would be more reasonable.
> >
> > You can at least use typeid.name() to order objects by their type.
> > Eg, you want to sort a polymorhphic container and you want all the
> > A objects together, all the B objects together, and so on.
>
> That's what type_info::before() is for.
> type_info::name() is not useful in this respect, since it is not
> guaranteed to be unique. The simplest conforming implementation
> reads:
>
> const char* type_info::name() { return ""; }

I've come to much the same conclusion about the implementation of
name(). However, check out the wording of before():

  18.5.1 Class type_info

    ...

      bool before(const type_info& rhs) const;

  5 Effects: Compares the current object with rhs.
  6 Returns: true if *this precedes rhs in the implementation's
    collation order.

Some have suggested that before() could return a different
sorted order of types in different runs. But the last two
words have a strong implication: We use SOME collating
sequence. It doesn't specifically state that the collating
sequence is applied to the class name, but this is strongly
implied.

So, given a more reasonable implementation of name(), we
turn the tables and state that the simplest implementation
of before() is
    bool before(const type_info& rhs) const {
        return strcmp(name(), rhs.name())<0;
    }

--
AllanW@my-dejanews.com is a "Spam Magnet" -- never read.
Please reply in USENET only, sorry.

-----------== Posted via Deja News, The Discussion Network ==----------
http://www.dejanews.com/       Search, Read, Discuss, or Start Your Own

      [ Send an empty e-mail to c++-help@netlab.cs.rpi.edu for info ]
      [ about comp.lang.c++.moderated. First time posters: do this! ]
---
[ 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: "Paul D. DeRocco" <pderocco@ix.netcom.com>
Date: 1998/11/20
Raw View
Siemel Naran wrote:
>
> I used typeid to write a program to make typedefs.  Eg, given the
> types with sizeofs:
>    signed char==1, short==2, int==4, long==4
> my program generates typedefs:
>
> typedef signed char int8 ;
> typedef short       int16;
> typedef int         int32;
>
> To get this done, we use a template member func
>
> class Typedef
> {
>      //stuff
>      template <class T> Typedef& operator<<(T);
>      void write() const;
> };
>
> (Typedef("int") << (signed char)0 << (short)0 << (int)0 << (long)0) .
>         write();
>
> Well, I admit this isn't a very profound use :).

In this application, wouldn't it be easier and clearer just to write a
switch or if/then/else to decode the sizes of things?

--

Ciao,
Paul
---
[ 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: Biju Thomas <bijuthom@ibm.net>
Date: 1998/11/20
Raw View
In article <72sepd$5mj$1@nnrp1.dejanews.com>,
  AllanW@my-dejanews.com wrote:
>
>   18.5.1 Class type_info
>
>     ...
>
>       bool before(const type_info& rhs) const;
>
>   5 Effects: Compares the current object with rhs.
>   6 Returns: true if *this precedes rhs in the implementation's
>     collation order.
>
> Some have suggested that before() could return a different
> sorted order of types in different runs.

I believe that is not possible, as the collation order of classes doesn't
change between runs. It is hard-wired in the object code.

> But the last two
> words have a strong implication: We use SOME collating
> sequence. It doesn't specifically state that the collating
> sequence is applied to the class name, but this is strongly
> implied.

Where is it implied? It doesn't say that collating sequence should be based on
class name. Just for arguments' sake, it can be based on class name and the
class-hierarchy, in which, a base class and its child classes are adjacent in
the collating sequence.

> So, given a more reasonable implementation of name(), we
> turn the tables and state that the simplest implementation
> of before() is
>     bool before(const type_info& rhs) const {
>         return strcmp(name(), rhs.name())<0;
>     }
>

It doesn't say that the collating sequence should have some regularity in a
human readable form. So, the implementation can define anything as its
collation order. The 'type_info::before' function is fine for sorting objects
internally inside the program. But, to show objects in an ordered sequence to
users, it will be better not to rely on the 'type_info::before' function.
Instead, implement your own ordering method.

Regards,
Biju Thomas

-----------== Posted via Deja News, The Discussion Network ==----------
http://www.dejanews.com/       Search, Read, Discuss, or Start Your Own


[ 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: 1998/11/18
Raw View
AllanW@my-dejanews.com wrote:
...
> say that, but it doesn't do that either. Here's what it DOES
> say (yes, I finally downloaded the full IS):

Good idea! :-)

>   18.5.1 Class type_info                    [lib.type.info]
>
>       ...
>
>           const char* name() const;
>     7 Returns: an implementation-defined NTBS.
>     8 Notes: The message may be a null-terminated multibyte
>       string (17.3.2.1.3.2), suitable for conversion and
>       display as a wstring (21.2, 22.2.1.5)
...
> Given all of that, I have to agree with you, Nathan.
> Application programmers should avoid this feature for now,
> especially if they want to write portable code.

No, don't avoid it completely; it can be very helpful in debugging
output, if implemented at all reasonably. I can't think of any other use
for it, though.
---
[ 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: sbnaran@localhost.localdomain.COM (Siemel Naran)
Date: 1998/11/18
Raw View
On 18 Nov 98 18:34:39 GMT, James Kuyper <kuyper@wizard.net> wrote:

>No, don't avoid it completely; it can be very helpful in debugging
>output, if implemented at all reasonably. I can't think of any other use
>for it, though.

I used typeid to write a program to make typedefs.  Eg, given the types
with sizeofs:
   signed char==1, short==2, int==4, long==4
my program generates typedefs:

typedef signed char int8 ;
typedef short       int16;
typedef int         int32;


To get this done, we use a template member func

class Typedef
{
     //stuff
     template <class T> Typedef& operator<<(T);
     void write() const;
};

(Typedef("int") << (signed char)0 << (short)0 << (int)0 << (long)0) . write();


Well, I admit this isn't a very profound use :).

--
----------------------------------
Siemel B. Naran (sbnaran@uiuc.edu)
----------------------------------


[ 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: 1998/11/18
Raw View
Siemel Naran wrote:
>
> On 18 Nov 98 18:34:39 GMT, James Kuyper <kuyper@wizard.net> wrote:
>
> >No, don't avoid it completely; it can be very helpful in debugging
> >output, if implemented at all reasonably. I can't think of any other use
> >for it, though.
>
> I used typeid to write a program to make typedefs.  Eg, given the types
> with sizeofs:
>    signed char==1, short==2, int==4, long==4
> my program generates typedefs:
>
> typedef signed char int8 ;
> typedef short       int16;
> typedef int         int32;
>
> To get this done, we use a template member func
>
> class Typedef
> {
>      //stuff
>      template <class T> Typedef& operator<<(T);
>      void write() const;
> };
>
> (Typedef("int") << (signed char)0 << (short)0 << (int)0 << (long)0) . write();
>
> Well, I admit this isn't a very profound use :).

I don't see any use of typeid().name() in that code. I would guess that
your code assumes that typeid(int).name() to return "int". Would it do
what you need it to do if typeid(int).name() instead returned "C int" or
"integer" or "0x11234"?

That's what I mean by not being useful. A reasonable implementation will
make name() return something understandable, but there's no guarantee
that it will be appropriate for insertion in a type declaration.

That gives me an idea: if you want to standardize name()'s return value,
require it to be a string that could be used to declare an object of the
same type. Combined with a requirement that two objects of the same
most-derived type must have identical name()s, that would remove a lot
of the ambiguity. It would also make the value useful in automatic code
generation.
There's probably something seriously wrong with this idea.



[ 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 Wade" <bill.wade@stoner.com>
Date: 1998/11/19
Raw View
AllanW@my-dejanews.com wrote in message <72pr9j$sdu$1@nnrp1.dejanews.com>...
>I think that this definition would be sufficient for a standard
>return value from typeid.name():
>    staticfile:: opt
>    namespaces:: opt
>    type:: opt
>    member(args)nesting:: opt
>    enclosing_classes:: opt
>    typename

How about unnamed classes?

struct { int a; } x, y;
struct { int a; } z;

I believe x and y have the same type as each other, but z has another type.

As an aside, the compiler I use most often says x and z are not assignment
compatible, but they do have the same type_info.
---
[ 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: 1998/11/19
Raw View
Ken Walter wrote:
>
> In your case the two identically declared struct in two different
> files
> I would NOT consider the same type!
> They could have entirely different meanings even though they look
> similar.
> If I declared a variable X in two separate files I would not assume
> they were
> the same variable unless I specificed it somehow, so why should the
> classes
> declared in two different files be the same.


Actually, you do consider two identically declared structs in two
different files to be the same type, you just don't know it. <g>
Remember, the preprocessor sees the source code (conceptually) before
the compiler does. So when you write a header file and #include it in
two different source files you have, in effect, two separate definitions
of everything defined in the header, including classes.

sample.h
--------
class C {};
void f(C);

sample1.cpp
-----------
#include "sample.h"
void f(C)
{
}

sample2.cpp
-----------
#include "sample.h"
int main()
{
C c;
f(c);
}

This would not work if the two definitions of C that the compile saw
when it compiled sample1.cpp and sample2.cpp were not treated as
defining the same type.

--
Pete Becker
Dinkumware, Ltd.
http://www.dinkumware.com


      [ Send an empty e-mail to c++-help@netlab.cs.rpi.edu for info ]
      [ about comp.lang.c++.moderated. First time posters: do this! ]


[ 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: Hyman Rosen <hymie@prolifics.com>
Date: 1998/11/17
Raw View
Ken Walter wrote:
> On Fri, 13 Nov 1998 16:35:03, Hyman Rosen <hymie@prolifics.com> wrote:
> > The struct a in each file is the same type. Therefore tying a type
> > name to a file name is meaningless and misleading.
>
> So is strictly by name.
> struct a{ int i, double d}; in one file
> and
> struct a{ char c; int j}; in another are not the same.

If these files are part of the same program, then the program is in
violation of the one-definition-rule. The behavior of such a program
is undefined, and the compiler is not required to diagnose it.
---
[ 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: AllanW@my-dejanews.com
Date: 1998/11/18
Raw View
In article <72q7rh$pcd$1@shell7.ba.best.com>,
  ncm@nospam.cantrip.org (Nathan Myers) wrote:
>
> <AllanW@my-dejanews.com> wrote:
> >  ncm@nospam.cantrip.org (Nathan Myers) wrote:
> >> But I don't think you're looking at this right.  It's left completely
> >> open-ended what that function returns, so first find something useful
> >> you want to do with it, then define it to do something helpful for that
> >> case and write patches for gcc, or persuade your compiler vendor to add
> >> a compiler option to implement it your way.
> >
> >I respectfully disagree. ...
> >The proper avenue is to understand the tool as much as possible,
> >so that I can use it when it's appropriate and avoid it when
> >it's not appropriate.
>
> By that criterion your choice is very simple: you must avoid
> the feature entirely.  It is in the standard specifically as
> a hook for implementers and users to negotiate useful
> definitions for.  If you don't want to participate in that,
> then you can only wait until somebody else does it for you.

Avoid it entirely? Compilers will support the feature! Some
programmer poured sweat and tears into this particular feature
on my compiler, just to make sure it's right, and you're telling
me not to use it at all?

If the feature exists "specifically as a hook", as you say,
then the standard ought to say so. But in fact the word "hook"
does not occur anywhere in the standard. OTOH, if the standard
meant to specify what the returned value should be, it ought to
say that, but it doesn't do that either. Here's what it DOES
say (yes, I finally downloaded the full IS):

  18.5.1 Class type_info                    [lib.type.info]

      ...

          const char* name() const;
    7 Returns: an implementation-defined NTBS.
    8 Notes: The message may be a null-terminated multibyte
      string (17.3.2.1.3.2), suitable for conversion and
      display as a wstring (21.2, 22.2.1.5)

Paragraph 8 is clearly intended to convey the fact that the
returned value might or might not contain double-byte
characters. But I find the wording to be fascinating.

"The message" implies that although the null-terminated byte
string is still implementation-defined, it is expected to be
a message of some sort. This could hardly fit the
Object-Oriented concept called "message passing" since that
is implemented in C++ as a call to a member function.

A further clue comes from the phrase "suitable for ... display".
I'm left with the understanding that the "message" is supposed
to be human-readable, although this isn't explicit.

To summarize, we know that name() returns a message in the form
of an unspecified implementation-defined human-readable
null-terminated byte string which may or may not contain
double-byte characters. Programmers will be tempted to infer a
significance to the message, but since it's purpose was never
stated we can't prove that inference to be right or wrong; and
even if it's right, we can't assume that the message has any
particular format, or even properties such as being unique for
each class, or really anything at all about it except that
it's human-readable.

Given all of that, I have to agree with you, Nathan.
Application programmers should avoid this feature for now,
especially if they want to write portable code.

--
AllanW@my-dejanews.com is a "Spam Magnet" -- never read.
Please reply in USENET only, sorry.

-----------== Posted via Deja News, The Discussion Network ==----------
http://www.dejanews.com/       Search, Read, Discuss, or Start Your Own
---
[ 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: AllanW@my-dejanews.com
Date: 1998/11/14
Raw View
In article <72fqqj$uf$1@shell7.ba.best.com>,
  ncm@nospam.cantrip.org (Nathan Myers) wrote:
>
> <AllanW@my-dejanews.com> wrote:
> >What I wonder, now, is exactly what value name() has. Why is
> >it in the standard at all? If I knew it's purpose, my
> >expectations would be more reasonable.
>
> The answer has already been posted.  It is a hook intended
> for implementers who wish to provide support for persistence,
> distributed computation, and related technologies.  It was
> left implementation-defined to allow those implementers to
> choose what to support and how to support it.  It's meaningful
> only in reference to a particular implementer.

Okay, now we are getting somewhere. If the idea is to support
persistance, then we don't need the name to have any
human-detectable resemblance to the actual class name in the source
code.

But we do need the name to be EXACTLY the same from one program run
to the next ... in fact, even if the program is recompiled and then
run. (Because the class name will be written into persistant
storage, and later used as the type to re-constitute the object.)
Therefore, the returned name should at least be BASED on the actual
source class name -- for instance, the "decorated" (mangled) name
could be used. Then we could always re-read our persistant storage,
provided we were on the same compiler (and provided that they
didn't change the typeid.name()-text scheme).

This pretty much eliminates David Tribble's idea of using the
v-table address, which would change when recompiled with trivial
changes to the program.

--
AllanW@my-dejanews.com is a "Spam Magnet" -- never read.
Please reply in USENET only, sorry.

-----------== Posted via Deja News, The Discussion Network ==----------
http://www.dejanews.com/       Search, Read, Discuss, or Start Your Own
---
[ 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: AllanW@my-dejanews.com
Date: 1998/11/14
Raw View
> On 12 Nov 1998 09:33:05 -0500, AllanW@my-dejanews.com
> >What exactly is the purpose of name()?
> >
> >I think that I at least half-expected name() to return something
> >intended for human readers. Something that would contain enough
> >information for a human reader to find the class in source files.
> >For instance,
> >    "C"             for the global class
> >    "main()::C"     for the local class
> >    "main()1::C"    for the nested local class

In article <slrn74m7a4.onj.sbnaran@localhost.localdomain>,
  sbnaran@KILL.uiuc.edu wrote:
> First off, I agree with you.  There is a technical problem with local
> classes:
>
> template <class>
> void f()
> {
>      { struct X { int    x; }; cout << typeid(x).name() << '\n'; }
>      { struct X { double x; }; cout << typeid(x).name() << '\n'; }
>      { { struct X { short x; }; cout << typeid(x).name() << '\n'; } }
>      struct X { double x; }; cout << typeid(x).name() << '\n';
> }
>
> All three X's are different so should return different strings.  But
> what are these strings?  For f<int>, we could get
>
> f<int>(){1}::X
> f<int>(){}{1}::X
> f<int>(){}{}{{1}}::X
> f<int>(){}{}::X
>
> But local classes like these don't really occur in practice (I think),
> so it is not worth the trouble to standardize the naming convention.

I don't want to standardize the naming convention. I do think that the
names should at least be unique.

> For classes at namespace scope, typeid.name() can be easily standardized
> and would be very useful to everyone.

But we didn't. The standard leaves this open.

What I would like is at least a guarantee that the name will be
consistent (even in the face of recompiles) and unique.

> Classes in functions or unnamed
> namespaces are usually helper classes and inaccessible to the rest of
> the program anyway, so we usually don't care what their typeid.name()
> is anyway.

Perhaps. If providing unique names across all classes turned out to
be too much of a burden on implementors, I would settle for the unique
guarantee on global or namespace classes.

But I'm not convinced that the burden is that much. The compiler
probably has the unique name in the symbol table somewhere anyway.
Displaying the name in a human-readable format while keeping all
of the unique portions shouldn't be that difficult, should it?

> So a nice rule for C++ would be to standardize typeid().name()
> for classes at namespace scope (which includes nested classes), but
> leave the conventions for local classes and classes in unnamed namespaces
> up to the implementation.

I could live with that.

> >What I wonder, now, is exactly what value name() has. Why is
> >it in the standard at all? If I knew it's purpose, my
> >expectations would be more reasonable.
>
> You can at least use typeid.name() to order objects by their type.
> Eg, you want to sort a polymorhphic container and you want all the
> A objects together, all the B objects together, and so on.

This purpose (which contradicts a different post on this thread)
would mean that each class type would have to return a unique name,
but there would be no requirement for it to be human-readable at all,
nor even unique from one program run to the next. David Tribble's
idea for using the v-table address in hex would probably work just
fine for this purpose.

--
AllanW@my-dejanews.com is a "Spam Magnet" -- never read.
Please reply in USENET only, sorry.

-----------== Posted via Deja News, The Discussion Network ==----------
http://www.dejanews.com/       Search, Read, Discuss, or Start Your Own
---
[ 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 Wade" <bill.wade@stoner.com>
Date: 1998/11/14
Raw View

Valentin Bonnard wrote in message <364A250D.5E9E@pratique.fr>...
>David R Tribble wrote:
>
>> But it seems to me that in order to make type_info::name()
>> behave in the most reasonable fashion, typeid() ought to return a
>> unique string for every type in the program.
>
>But why ? What's the point ?


I presume that "before()" is present to allow types to be used as keys in
maps or sets.  Unique strings would allow types to be used as keys in
hash_maps.

If a developer wants unique strings (or integers) for debugging purposes, he
can already implement them using a map:

// DISCLAIMER: Instant hack.  Use at your own risk

  int Id(const type_info& t)
  {
    static map<type_info*, int, compare> type_map;
    static int next_id = 1;
    if(type_map[&t] == 0)
      type_map[&t] = next_id++;    // Assume no overflow.
    return type_map[&t];
  }

Of course on many implementations it is simpler to cast &t to an appropriate
integer type.

I'll leave it as an exercise for the reader to convert a unique integer into
a unique string ;-)



      [ Send an empty e-mail to c++-help@netlab.cs.rpi.edu for info ]
      [ about comp.lang.c++.moderated. First time posters: do this! ]



[ 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: icedancer.zamboni@ibm.zamboni.net (Ken Walter)
Date: 1998/11/14
Raw View
On Fri, 13 Nov 1998 16:35:03, Hyman Rosen <hymie@prolifics.com> wrote:

> Ken Walter wrote:
> > The type should be prefixed by all its enclosing scopes like:
> >  <Header File Name>::<Namespaces/Enclosing Classes>*::typeName.
> > Then two different programs using the same header on two different
> > CPUs will have then same name for the same type.
>
> This is incorrect for C++, because type equivalence is by name.
> I am allowed to have the following:
>
> a1.cc: struct a { }; a f() { return a(); }
> a2.cc: struct a { }; extern a f(); a g() { return f(); }
>
> The struct a in each file is the same type. Therefore tying a type
> name to a file name is meaningless and misleading.

So is strictly by name.
struct a{ int i, double d}; in one file
and
struct a{ char c; int j}; in another are not the same.

In your case the two identically declared struct in two different
files
I would NOT consider the same type!
They could have entirely different meanings even though they look
similar.
If I declared a variable X in two separate files I would not assume
they were
the same variable unless I specificed it somehow, so why should the
classes
declared in two different files be the same.


 Ken Walter

Remove .zamboni to reply
All the above is hearsay and the opinion of no one in particular

      [ Send an empty e-mail to c++-help@netlab.cs.rpi.edu for info ]
      [ about comp.lang.c++.moderated. First time posters: do this! ]



[ 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: ncm@nospam.cantrip.org (Nathan Myers)
Date: 1998/11/14
Raw View
<AllanW@my-dejanews.com> wrote:
>  ncm@nospam.cantrip.org (Nathan Myers) wrote:
>> It is a hook intended
>> for implementers who wish to provide support for persistence,
>> distributed computation, and related technologies.  It was
>> left implementation-defined to allow those implementers to
>> choose what to support and how to support it.  It's meaningful
>> only in reference to a particular implementer.
>
>Okay, now we are getting somewhere. If the idea is to support
>persistance, then we don't need the name to have any
>human-detectable resemblance to the actual class name in the
>source code.

No.  Persistence is one of the possible uses, but it is not "the idea".

>This pretty much eliminates David Tribble's idea of using the
>v-table address, which would change when recompiled with trivial
>changes to the program.

David Tribble's idea is conforming, and might even be useful in
some non-obvious cases.

But I don't think you're looking at this right.  It's left completely
open-ended what that function returns, so first find something useful
you want to do with it, then define it to do something helpful for that
case and write patches for gcc or persuade your compiler vendor to add
a compiler option to implement it your way.  For uses where you must
communicate between independent programs it may not matter how local
type names are represented, as long as they don't collide with linkage
names.

I don't see how this discussion belongs in c.s.c++ any longer, though.

[ moderator's note: Discussion about how language features are
  defined to work, or how they ought to work, fits the charter
  of the newsgroup. -sdc ]

--
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: apjenkins@my-dejanews.com
Date: 1998/11/14
Raw View
In article <slrn74m7a4.onj.sbnaran@localhost.localdomain>,
  sbnaran@KILL.uiuc.edu wrote:
> On 12 Nov 1998 09:33:05 -0500, AllanW@my-dejanews.com
> template <class>
> void f()
> {
>      { struct X { int    x; }; cout << typeid(x).name() << '\n'; }
>      { struct X { double x; }; cout << typeid(x).name() << '\n'; }
>      { { struct X { short x; }; cout << typeid(x).name() << '\n'; } }
>      struct X { double x; }; cout << typeid(x).name() << '\n';
> }
>

I assume you meant to write "typeid(X)" in each case above?

> >What I wonder, now, is exactly what value name() has. Why is
> >it in the standard at all? If I knew it's purpose, my
> >expectations would be more reasonable.
>
> You can at least use typeid.name() to order objects by their type.
> Eg, you want to sort a polymorhphic container and you want all the
> A objects together, all the B objects together, and so on.

You can't even use type_info::name() for that; nothing about
type_info::name() is guaranteed by the standard.  It could be the
empty string for all classes for example.  However, you can use
type_info::before() for ordering classes as you describe above.

--
Adam P. Jenkins
ajenkins at javanet dot com

-----------== Posted via Deja News, The Discussion Network ==----------
http://www.dejanews.com/       Search, Read, Discuss, or Start Your Own
---
[ 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: sbnaran@localhost.localdomain (Siemel Naran)
Date: 1998/11/16
Raw View
On 14 Nov 1998 07:44:19 -0500, AllanW@my-dejanews.com

>Perhaps. If providing unique names across all classes turned out to
>be too much of a burden on implementors, I would settle for the unique
>guarantee on global or namespace classes.

Additional point: nested class names should also be guaranteed.


>> So a nice rule for C++ would be to standardize typeid().name()
>> for classes at namespace scope (which includes nested classes), but
>> leave the conventions for local classes and classes in unnamed namespaces
>> up to the implementation.
>
>I could live with that.


>> You can at least use typeid.name() to order objects by their type.
>> Eg, you want to sort a polymorhphic container and you want all the
>> A objects together, all the B objects together, and so on.

>This purpose (which contradicts a different post on this thread)
>would mean that each class type would have to return a unique name,
>but there would be no requirement for it to be human-readable at all,
>nor even unique from one program run to the next. David Tribble's
>idea for using the v-table address in hex would probably work just
>fine for this purpose.

Yes, it is fine.  But we would like the order to be the same across
different compilers and different platforms and different compiles.
Suppose we have classes A, B, and C.  On platform 1,
type_info::name() is such that A comes before B comes before C.  On
platform 2, type_info::name() is such that A comes before C becomes
before B.  So sorting a polymorphic container on platform 1 gives a
different order than sorting on platform 2.  It is of course nice
that both platforms give a definite order.  But it is not nice that
the order that they give is different.  Eg,

Suppose the container std::vector<Base*> contains 5 elements:
   C,B,A,A,B

On platform 1, sort(begin(),end(),sorter()) results in:
   A,A,B,B,C

On platform 2, sort(begin(),end(),sorter()) results in:
   A,A,C,B,B


If type_info::name() were standardized, and the function
type_info::before() were implemented to call the name() function,
then both platform 1 and platform 2 would give the same order --
namely that of platform 1 above.  A definite order would no doubt
be useful to programmers.  It would also be useful to end users
of the program.  Eg, if I look at a sorted list of my Checks and
Deposits on an SGI and an Intel, it's comforting to see the same
exact results.

In this scenario, the function type_info::before() is useless.

--
----------------------------------
Siemel B. Naran (sbnaran@uiuc.edu)
----------------------------------

      [ Send an empty e-mail to c++-help@netlab.cs.rpi.edu for info ]
      [ about comp.lang.c++.moderated. First time posters: do this! ]


[ 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: AllanW@my-dejanews.com
Date: 1998/11/16
Raw View
In article <72j18p$r3$1@shell7.ba.best.com>,
  ncm@nospam.cantrip.org (Nathan Myers) wrote:
> But I don't think you're looking at this right.  It's left completely
> open-ended what that function returns, so first find something useful
> you want to do with it, then define it to do something helpful for that
> case and write patches for gcc or persuade your compiler vendor to add
> a compiler option to implement it your way.

I respectfully disagree.

Metephorically speaking, I'm asking what types of screws this
screwdriver fits. That way I won't misuse it. You're suggesting
that I find some screw I wish to use it on, and then go back to
the manufacturer and ask him to modify the screwdriver to fit.

Non-metephorically speaking, it doesn't make much sense to go
looking for a place where I wish that typeid::name() would work.
Even if I could then convince my vendor to change his compiler
to match my thinking, the code that relied on it would be
non-portable.

The proper avenue is to understand the tool as much as possible,
so that I can use it when it's appropriate and avoid it when
it's not appropriate.

--
AllanW@my-dejanews.com is a "Spam Magnet" -- never read.
Please reply in USENET only, sorry.

-----------== Posted via Deja News, The Discussion Network ==----------
http://www.dejanews.com/       Search, Read, Discuss, or Start Your Own


[ 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: Charles Hixson <charleshixsn@earthlink.net>
Date: 1998/11/16
Raw View
> Valentin Bonnard wrote in message <364A250D.5E9E@pratique.fr>...
> >David R Tribble wrote:
> >
> >> But it seems to me that in order to make type_info::name()
> >> behave in the most reasonable fashion, typeid() ought to return a
> >> unique string for every type in the program.
> >
> >But why ? What's the point ?
>
Most of the proposals for type_info::name() fall short of my desire.  I
desire to be able to read in a chunk of information, call it a type
name, that was written on another system, and to properly recognize it.
This requires a bit more than tpe_info::name(), but a "proper" version
of it would be a good starting point.  Failing that, this is another
chunk of code that I have to write for my routines, and which will be
unuseable by you on your routines. (After all, I'll take shortcuts that
don't harm my purpose, even though they do decrease global utility.
Besides, I'm not THAT experienced at C++, so my code wouldn't be optimal
anyway. [Which means I REALLY wish it were a part of the 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: Christopher Eltschka <celtschk@physik.tu-muenchen.de>
Date: 1998/11/16
Raw View
Siemel Naran wrote:

[...]

> >What I wonder, now, is exactly what value name() has. Why is
> >it in the standard at all? If I knew it's purpose, my
> >expectations would be more reasonable.
>
> You can at least use typeid.name() to order objects by their type.
> Eg, you want to sort a polymorhphic container and you want all the
> A objects together, all the B objects together, and so on.

That's what type_info::before() is for.
type_info::name() is not useful in this respect, since it is not
guaranteed to be unique. The simplest conforming implementation
reads:

const char* type_info::name() { return ""; }
---
[ 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: ncm@nospam.cantrip.org (Nathan Myers)
Date: 1998/11/17
Raw View
<AllanW@my-dejanews.com> wrote:
>  ncm@nospam.cantrip.org (Nathan Myers) wrote:
>> But I don't think you're looking at this right.  It's left completely
>> open-ended what that function returns, so first find something useful
>> you want to do with it, then define it to do something helpful for that
>> case and write patches for gcc, or persuade your compiler vendor to add
>> a compiler option to implement it your way.
>
>I respectfully disagree. ...
>The proper avenue is to understand the tool as much as possible,
>so that I can use it when it's appropriate and avoid it when
>it's not appropriate.

By that criterion your choice is very simple: you must avoid
the feature entirely.  It is in the standard specifically as
a hook for implementers and users to negotiate useful
definitions for.  If you don't want to participate in that,
then you can only wait until somebody else does it for you.

--
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: "Bill Wade" <bill.wade@stoner.com>
Date: 1998/11/17
Raw View

Ken Walter wrote in message ...

>struct a{ int i, double d}; in one file
>and
>struct a{ char c; int j}; in another are not the same.


This is not legal C++.  It is legal C.  In practice, very few compilers
will complain.

In C the scope of a global class is its file.  In C++, the scope of a
global class is its namespace.



      [ Send an empty e-mail to c++-help@netlab.cs.rpi.edu for info ]
      [ about comp.lang.c++.moderated. First time posters: do this! ]



[ 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: Christopher Eltschka <celtschk@physik.tu-muenchen.de>
Date: 1998/11/17
Raw View
Ken Walter wrote:
>
> On Fri, 13 Nov 1998 16:35:03, Hyman Rosen <hymie@prolifics.com> wrote:
>
> > Ken Walter wrote:
> > > The type should be prefixed by all its enclosing scopes like:
> > >  <Header File Name>::<Namespaces/Enclosing Classes>*::typeName.
> > > Then two different programs using the same header on two different
> > > CPUs will have then same name for the same type.
> >
> > This is incorrect for C++, because type equivalence is by name.
> > I am allowed to have the following:
> >
> > a1.cc:        struct a { }; a f() { return a(); }
> > a2.cc:        struct a { }; extern a f(); a g() { return f(); }
> >
> > The struct a in each file is the same type. Therefore tying a type
> > name to a file name is meaningless and misleading.
>
> So is strictly by name.
> struct a{ int i, double d}; in one file
> and
> struct a{ char c; int j}; in another are not the same.

But this is not allowed by the standard (a diagnostic is not
required).

In addition, real compilers will get problems as well. Try:

// file1.cc

struct a { int i; };

void f(a) {}

// file2.cc

struct a { double d; }; // assumed a different type

void f(a) {}

int main() {}


I'd be very surprised if your compiler lets you link this.

>
> In your case the two identically declared struct in two different
> files
> I would NOT consider the same type!

You'll have to live with it.
Indeed, it follows directly of C++'s lack of module concept.
In Turbo Pascal, two identical records (the Pascal name of "struct")
with the same name, defined in different modules ("units" in TP
terminology) resolved to different types. (Standard Pascal of
course has no modules, therefore this rule would not make sense there).

> They could have entirely different meanings even though they look
> similar.
> If I declared a variable X in two separate files I would not assume
> they were
> the same variable unless I specificed it somehow, so why should the
> classes
> declared in two different files be the same.

Because, given the C separate compilation model which was inherited
by C++, this is the only definition which allows using the same type
in two or more files. (Remember, the preprocessor is - at least
originally, for some compilers still today - a separate program
which generates _one_ file for each translation unit, by textually
inserting the include files into the source file. Especially it's
a purely text-oriented tool without knowledge about the language.)


      [ Send an empty e-mail to c++-help@netlab.cs.rpi.edu for info ]
      [ about comp.lang.c++.moderated. First time posters: do this! ]
---
[ 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: AllanW@my-dejanews.com
Date: 1998/11/17
Raw View
> >David R Tribble wrote:
> >> But it seems to me that in order to make type_info::name()
> >> behave in the most reasonable fashion, typeid() ought to return a
> >> unique string for every type in the program.

> Valentin Bonnard wrote in message <364A250D.5E9E@pratique.fr>...
> >But why ? What's the point ?

In article <72i2vt$akl$1@uuneo.neosoft.com>,
  "Bill Wade" <bill.wade@stoner.com> wrote:
> I presume that "before()" is present to allow types to be used as keys
in
> maps or sets.  Unique strings would allow types to be used as keys in
> hash_maps.

That presumption is the crux of the matter. There are three things
that we might need:
    -- Consistent names; the name of a given class would be
       the same every time the program was run, probably
       even if the program was re-compiled.
    -- Human-readable names. The name does not need to be
       exactly the same as the name fed into the compiler,
       but it should be something that humans can instantly
       translate back to the original class name.
    -- Unique names; no two different classes would ever
       possibly have the same name.
       (So far, we've ignored the possiblity that the same
        class, used in two different translation units, might
        have two different names!)
The last two requirements tend to conflict with each other.
It's possible to devise a scheme which is both unique and
human readable, and I have proposed a scheme in another
post -- but the scheme is complicated, and the resulting
strings can sometimes be very very long.

Which of these possible requirements are, actually, required?
It depends on the purpose of typeid::name(). After all, we are
all assumed to be programmer/analysts; if we know the purpose
of a feature it should be easy for us to deduce the true
requirements. On November 12 I asked what the PURPOSE of
typeid::name() was. The responses:
    -- Nathan Myers wrote:
       > It is a hook intended for implementers who wish to
       > provide support for persistence, distributed
       > computation, and related technologies.
       To satisfy this the names must be unique and consistent,
       but we don't need them to be human-readable; we could
       use the "decorated" (aka mangled) name.
    -- James Kuyper wrote:
       >> I think that I at least half-expected name() to return
       >> something intended for human readers. Something that
       >> would contain enough information for a human reader to
       >> find the class in source files. For instance,
       [Unique examples elided]
       > You got it's purpose exactly correct, you're just
       > wanting more support for that purpose than the standard
       > provides.
       If James is correct, we need the name to be human-readable,
       which also implies consistent, but we could live without
       unique. For instance, in debugging, we could perhaps live
       with the root name alone, relying on the programmer to
       search the heirarchy and/or resolve ambiguity.
    -- Siemel Naran wrote:
       > You can at least use typeid.name() to order objects by
       > their type. Eg, you want to sort a polymorhphic container
       > and you want all the A objects together, all the B objects
       > together, and so on.
       For sorting the names must be unique, but we don't need them
       to be human-readable or even consistent.
    -- David R. Tribble wrote:
       [Note that he wrote this BEFORE I posed my question;
        it's not exactly a response, but it seems relevant]:
       > But it seems to me that in order to make type_info::name()
       > behave in the most reasonable fashion, typeid() ought to
       > return a unique string for every type in the program.
       > And this isn't that hard to do.  Consider an
       > implementation that simply returns a string representation
       > of the address of a type "descriptor" in hexadecimal form:
       David seems to suggest that unique names are the only
       requirement. Names in his scheme are not unique or even
       slightly human-readable.

Does anyone know who proposed that typeid should have a name()
function? Is that person active on this newsgroup? If so, please
tell us what the original purpose was. Does name(), as it is
currently specified, meet that purpose?

--
AllanW@my-dejanews.com is a "Spam Magnet" -- never read.
Please reply in USENET only, sorry.

-----------== Posted via Deja News, The Discussion Network ==----------
http://www.dejanews.com/       Search, Read, Discuss, or Start Your Own



      [ Send an empty e-mail to c++-help@netlab.cs.rpi.edu for info ]
      [ about comp.lang.c++.moderated. First time posters: do this! ]
---
[ 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: AllanW@my-dejanews.com
Date: 1998/11/17
Raw View
> > Ken Walter wrote:
> > > The type should be prefixed by all its enclosing scopes like:
> > >  <Header File Name>::<Namespaces/Enclosing Classes>*::typeName.
> > > Then two different programs using the same header on two different
> > > CPUs will have then same name for the same type.

> On Fri, 13 Nov 1998 16:35:03, Hyman Rosen <hymie@prolifics.com> wrote:
> > This is incorrect for C++, because type equivalence is by name.
> > I am allowed to have the following:
> >
> > a1.cc: struct a { }; a f() { return a(); }
> > a2.cc: struct a { }; extern a f(); a g() { return f(); }
> >
> > The struct a in each file is the same type. Therefore tying a type
> > name to a file name is meaningless and misleading.

In article <eDcSHHgdulIC-pn2-5KZLtwFXmgUg@eir.stiscan.com>,
  icedancer.zamboni@ibm.zamboni.net (Ken Walter) wrote:
> So is strictly by name.
> struct a{ int i, double d}; in one file
> and
> struct a{ char c; int j}; in another are not the same.

This probably works in most compilers, but it is not legal code.

  3.2  One definition rule                               [basic.def.odr]

5 There  can be more than one definition of a class type (_class_)
[snip]                                   in a program provided that each
  definition appears in a different translation unit, and  provided  the
  definitions  satisfy the following requirements.  Given such an entity
  named D defined in more than one translation unit, then

  --each definition of D shall consist of the same sequence  of  tokens;
    and

  --in each definition of D, corresponding names, looked up according to
    _basic.lookup_, shall refer to an entity defined within the  defini-
    tion of D, or shall refer to the same entity, after overload resolu-
    tion (_over.match_) and after matching of partial template  special-
    ization  (_temp.over_),  except  that  a  name  can refer to a const
    object with internal or no linkage if the object has the same  inte-
    gral  or enumeration type in all definitions of D, and the object is
    initialized with a constant expression (_expr.const_), and the value
    (but  not the address) of the object is used, and the object has the
    same value in all definitions of D; and
[snip]

> In your case the two identically declared struct in two different
> files
> I would NOT consider the same type!
> They could have entirely different meanings even though they look
> similar.
> If I declared a variable X in two separate files I would not assume
> they were
> the same variable unless I specificed it somehow, so why should the
> classes
> declared in two different files be the same.

And therefore, if they are both at global scope, the program is
ill-formed.

OTOH, specifying exactly the same tokens in two separate
translation units may be bad form, but it is not illegal
in C++.  For example,
    // first.cpp:
    struct X { int a; char b; };
    X func1() { X x; return x; }

    // second.cpp
    struct X { int a; char b; };
    X func2(int i) { X x; x.a=i; return x; }
This is completely legal; therefore, putting the header file
name in the typeid.name() string would be a bad idea.

However, it is legal for two different functions to define
local classes with the same name, and it is also legal to
create two different functions with the same name provided
that all (or all but one) are declared as static. And even
if this function was defined in a header file, the translation
unit that #included it could define local context or #defines
which would change it's meaning.

I think that this definition would be sufficient for a standard
return value from typeid.name():
    staticfile:: opt
    namespaces:: opt
    type:: opt
    member(args)nesting:: opt
    enclosing_classes:: opt
    typename
I'll explain each portion one at a time.

staticfile:: is the word "static" and then a space and the name
of the translation unit, if and only if the class is defined
within a file-scope static function. This would include
punctuation suitable to guarantee that the name was not a legal
class name; for most OS's the period makes this automatic, but
some OS's will need for example to put the name in curly
brackets as in static {Filename}::

namespaces:: is the name of the namespace(s) that the class was
defined in. For nameless namespaces, use the name of the
translation unit as the namespace name, with the same "unique
name" guarantee as shown above for staticfile.

(Note that it is possible to use both staticfile and namespace,
if the namespace contains a static function.)

type:: is the full name of the enclosing class, if and only if
this class is defined within another class or within a member
function of another class. In that case, the full name is
found by applying these rules recursively.

member(args)nesting:: is the name of the enclosing function, if
the class is defined in a function. (If that function is a
member of another class, then the "type::" tag, above, will
also be used.) nesting is the number of left braces between the
start of the function and the class definition, excluding left
braces used in class definitions or initializers, and is omitted
if the number is 0.

enclosing_classes:: is used if this class is defined within
another class.

typename is the actual name used to define the class.

Example: Assume that the translation unit is "subprog" on a
system that does not use .Extension syntax in it's filenames.
    #include <iostream>
    namespace {
        class abc { // {subprog}::abc
            class def { int a; }; // {subprog}::abc::def
        };
        static void foo() {
            class abc {
            // static{subprog}::{subprog}::foo()::abc

                class def { int a; };
                // static{subprog}::{subprog}::foo()::abc::def
            };
        }
        class xyz {
            std::ostream func(int x, const char*y, int&z);
            class abc { // {subprog}::xyz::abc
               class def { int a; }; // {subprog}::xyz::abc::def
            };
        };
        std::ostream xyz::func(int a, const char*b, int&c) {
            class abc {
               // {subprog}::xyz::func(int,const char*,int&)::abc

               class def { int a; };
               // {subprog}::xyz::func(int,const char*,int&)::abc::def
            };

            int array[5] = { 1, 2, 3, 4, 5 };

            { // Left brace #1

                class abc {
                // {subprog}::xyz::func(int,const char*,int&)1::abc

                    class def { int a; };
                    // {subprog}::xyz::func(int,const
char*,int&)1::abc::def

            }

            { // Left brace #2

                class abc {
                // {subprog}::xyz::func(int,const char*,int&)2::abc

                    class def { int a; };
                    // {subprog}::xyz::func(int,const
char*,int&)2::abc::def
            }
        }
    };

--
AllanW@my-dejanews.com is a "Spam Magnet" -- never read.
Please reply in USENET only, sorry.

-----------== Posted via Deja News, The Discussion Network ==----------
http://www.dejanews.com/       Search, Read, Discuss, or Start Your Own



      [ Send an empty e-mail to c++-help@netlab.cs.rpi.edu for info ]
      [ about comp.lang.c++.moderated. First time posters: do this! ]
---
[ 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: Valentin Bonnard <bonnardv@pratique.fr>
Date: 1998/11/17
Raw View
Ken Walter wrote:

> In your case the two identically declared struct in two different
> files I would NOT consider the same type!
> They could have entirely different meanings even though they look
> similar. If I declared a variable X in two separate files I would not assume
> they were the same variable unless I specificed it somehow, so why should the
> classes declared in two different files be the same.

Then two different translation units can _never_ talk about
the same type. Very interresting definition.

Or try to define type equivalence another way.

--

Valentin Bonnard                mailto:bonnardv@pratique.fr
info about C++/a propos du C++: http://pages.pratique.fr/~bonnardv/


[ 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: ncm@nospam.cantrip.org (Nathan Myers)
Date: 1998/11/13
Raw View
<AllanW@my-dejanews.com> wrote:
>What I wonder, now, is exactly what value name() has. Why is
>it in the standard at all? If I knew it's purpose, my
>expectations would be more reasonable.

The answer has already been posted.  It is a hook intended
for implementers who wish to provide support for persistence,
distributed computation, and related technologies.  It was
left implementation-defined to allow those implementers to
choose what to support and how to support it.  It's meaningful
only in reference to a particular implementer.

(posted only to comp.std.c++; cross-posting in moderated newsgroups is
discouraged by the moderators.)

--
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: sbnaran@localhost.localdomain (Siemel Naran)
Date: 1998/11/13
Raw View
On 12 Nov 1998 09:33:05 -0500, AllanW@my-dejanews.com

>What exactly is the purpose of name()?
>
>I think that I at least half-expected name() to return something
>intended for human readers. Something that would contain enough
>information for a human reader to find the class in source files.
>For instance,
>    "C"             for the global class
>    "main()::C"     for the local class
>    "main()1::C"    for the nested local class

First off, I agree with you.  There is a technical problem with local
classes:

template <class>
void f()
{
     { struct X { int    x; }; cout << typeid(x).name() << '\n'; }
     { struct X { double x; }; cout << typeid(x).name() << '\n'; }
     { { struct X { short x; }; cout << typeid(x).name() << '\n'; } }
     struct X { double x; }; cout << typeid(x).name() << '\n';
}

All three X's are different so should return different strings.  But
what are these strings?  For f<int>, we could get

f<int>(){1}::X
f<int>(){}{1}::X
f<int>(){}{}{{1}}::X
f<int>(){}{}::X

But local classes like these don't really occur in practice (I think),
so it is not worth the trouble to standardize the naming convention.
For classes at namespace scope, typeid.name() can be easily standardized
and would be very useful to everyone.  Classes in functions or unnamed
namespaces are usually helper classes and inaccessible to the rest of
the program anyway, so we usually don't care what their typeid.name()
is anyway.  So a nice rule for C++ would be to standardize typeid().name()
for classes at namespace scope (which includes nested classes), but
leave the conventions for local classes and classes in unnamed namespaces
up to the implementation.


>What I wonder, now, is exactly what value name() has. Why is
>it in the standard at all? If I knew it's purpose, my
>expectations would be more reasonable.

You can at least use typeid.name() to order objects by their type.
Eg, you want to sort a polymorhphic container and you want all the
A objects together, all the B objects together, and so on.

--
----------------------------------
Siemel B. Naran (sbnaran@uiuc.edu)
----------------------------------

      [ Send an empty e-mail to c++-help@netlab.cs.rpi.edu for info ]
      [ about comp.lang.c++.moderated. First time posters: do this! ]
---
[ 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: 1998/11/13
Raw View
AllanW@my-dejanews.com wrote:
...
> What exactly is the purpose of name()?
>
> I think that I at least half-expected name() to return something
> intended for human readers. Something that would contain enough
> information for a human reader to find the class in source files.
> For instance,
>     "C"             for the global class
>     "main()::C"     for the local class
>     "main()1::C"    for the nested local class
> But if the standard doesn't say anything about this, then
> clearly my expectations were too high.
>
> What I wonder, now, is exactly what value name() has. Why is
> it in the standard at all? If I knew it's purpose, my
> expectations would be more reasonable.

You got it's purpose exactly correct, you're just wanting more support
for that purpose than the standard provides. As standard is actually
written, whether or not name() is actually useful  is entirely a quality
of implementation issue.
I gather that the reason for this is that agreement could not be reached
on a general scheme for uniquely naming types, or that it was felt
inappropriate to mandate any particular scheme.

      [ Send an empty e-mail to c++-help@netlab.cs.rpi.edu for info ]
      [ about comp.lang.c++.moderated. First time posters: do this! ]
---
[ 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: nimel@hem1.passagen.se
Date: 1998/11/13
Raw View
In article <3648DE67.3F87@noSPAM.central.beasys.com>,
  dtribble@technologist.com wrote:

...

> True.  But it seems to me that in order to make type_info::name()
> behave in the most reasonable fashion, typeid() ought to return a
> unique string for every type in the program.
>
> And this isn't that hard to do.  Consider an implementation that
> simply returns a string representation of the address of a type
> "descriptor" in hexadecimal form:
>
>     cout << typeid(float).name();  // Prints "C0ED0040"
>
>     class C { ... };
>     cout << typeid(C).name();      // Prints "C0EDB998"
>
>     {
>         class C { ... };
>         cout << typeid(C).name();  // Prints "C0EDBA72"
>     }
>
>     {
>         class C { ... };
>         cout << typeid(C).name();  // Prints "C0EDBABE"
>     }
>
> (No objects have to actually exist at the addresses printed, of
> course.)
>
> I believe it's more useful for typeid().name() to return non-equal
> names for truly non-like types, since I believe code that uses
> typeid() is more likely to want to know when objects have different
> types.  (Section 18.5.1 says nothing about type_info::operator=()
> returning false if the types are different; that can be inferred,
> but it's not explicitly stated.  Even less is guaranteed for
> the result of type_info::name().)
>
> Of course, this might conflict with other people's views, e.g.,
> that typeid().name() should return the same name for a given type
> from one program execution to the next.  My example implementation
> above doesn't necessarily guarantee this behavior.

This definitly conflict with my view. The only real use I so far
have had of type_info.name is to implement some relativly smart
trace macros for debugging purpose. My macros are perfectly
portable, but only useful on implementations where name() returns
something that can be understod by the programmer.

Furthermore, I if you want something unique (such as the address) why
not just take the address of the object and convert it to a string
yourself? (Not that I think it would be useful for anything at all...)

For a unique name to be useful, I think it is also necessary to require
that the implementation returns the same name for a specific type
every time the program is run. (Something that is not necessarly true
for the address of the object). If this behaviour was enforced, the
name function could be used to implement things like "virtual
constructors".

/Niklas Mellin

-----------== Posted via Deja News, The Discussion Network ==----------
http://www.dejanews.com/       Search, Read, Discuss, or Start Your Own


      [ Send an empty e-mail to c++-help@netlab.cs.rpi.edu for info ]
      [ about comp.lang.c++.moderated. First time posters: do this! ]
---
[ 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: Valentin Bonnard <bonnardv@pratique.fr>
Date: 1998/11/13
Raw View
David R Tribble wrote:

> But it seems to me that in order to make type_info::name()
> behave in the most reasonable fashion, typeid() ought to return a
> unique string for every type in the program.

But why ? What's the point ?

> There's probably also the opinion that typeid().name() should return
> a string that resembles the actual type name, so that it is useful
> when printed as a debug trace (for example).  My example
> implementation fails on this account, too.

Yes !

I am sorry, I don't see any advantage with your
``naming convention''.

--

Valentin Bonnard                mailto:bonnardv@pratique.fr
info about C++/a propos du C++: http://pages.pratique.fr/~bonnardv/


      [ Send an empty e-mail to c++-help@netlab.cs.rpi.edu for info ]
      [ about comp.lang.c++.moderated. First time posters: do this! ]
---
[ 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: Hyman Rosen <hymie@prolifics.com>
Date: 1998/11/13
Raw View
Ken Walter wrote:
> The type should be prefixed by all its enclosing scopes like:
>  <Header File Name>::<Namespaces/Enclosing Classes>*::typeName.
> Then two different programs using the same header on two different
> CPUs will have then same name for the same type.

This is incorrect for C++, because type equivalence is by name.
I am allowed to have the following:

a1.cc: struct a { }; a f() { return a(); }
a2.cc: struct a { }; extern a f(); a g() { return f(); }

The struct a in each file is the same type. Therefore tying a type
name to a file name is meaningless and misleading.


      [ Send an empty e-mail to c++-help@netlab.cs.rpi.edu for info ]
      [ about comp.lang.c++.moderated. First time posters: do this! ]


[ 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: 1998/11/13
Raw View
Ken Walter wrote:
>
>
> The type should be prefixed by all its enclosing scopes like:
>  <Header File Name>::<Namespaces/Enclosing Classes>*::typeName.
> Then two different programs using the same header on two different
> CPUs
> will have then same name for the same type.
>

And defining the same class in two different header files (yes, this is
legal, so long as the definitions are "the same") will result in
different names for the same type.

--
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: David R Tribble <david.tribble@noSPAM.central.beasys.com>
Date: 1998/11/11
Raw View
AllanW@my-dejanews.com wrote:
>> I compiled this code in MSVC5.0
>>     #include <iostream>
>>     class C { int x; };
>>     int main() {
>>         std::cout << typeid(::C).name() << std::endl;
>>         class C { float x; };
>>         std::cout << typeid(C).name() << std::endl;
>>         { class C { char *x; };
>>           std::cout << typeid(C).name() << std::endl; }
>>     }
>> The result was:
>>     class C
>>     class C
>>     class C
>> Would someone please confirm that this is NOT what was
>> supposed to happen?

Paul D. DeRocco wrote:
> If you're expecting type_info::name() to return names that match what
> one would write in the source code, then the implementation did the
> "right" thing. If you're hoping for a unique name for every type, then
> obviously it did the "wrong" thing. However, it can't do both at the
> same time, in the presence of local names. It is only by within a
> single scope (e.g., global scope) that one can have valid
> source-code-matching names that are also guaranteed unique.

True.  But it seems to me that in order to make type_info::name()
behave in the most reasonable fashion, typeid() ought to return a
unique string for every type in the program.

And this isn't that hard to do.  Consider an implementation that
simply returns a string representation of the address of a type
"descriptor" in hexadecimal form:

    cout << typeid(float).name();  // Prints "C0ED0040"

    class C { ... };
    cout << typeid(C).name();      // Prints "C0EDB998"

    {
        class C { ... };
        cout << typeid(C).name();  // Prints "C0EDBA72"
    }

    {
        class C { ... };
        cout << typeid(C).name();  // Prints "C0EDBABE"
    }

(No objects have to actually exist at the addresses printed, of
course.)

I believe it's more useful for typeid().name() to return non-equal
names for truly non-like types, since I believe code that uses
typeid() is more likely to want to know when objects have different
types.  (Section 18.5.1 says nothing about type_info::operator=()
returning false if the types are different; that can be inferred,
but it's not explicitly stated.  Even less is guaranteed for
the result of type_info::name().)

Of course, this might conflict with other people's views, e.g.,
that typeid().name() should return the same name for a given type
from one program execution to the next.  My example implementation
above doesn't necessarily guarantee this behavior.

There's probably also the opinion that typeid().name() should return
a string that resembles the actual type name, so that it is useful
when printed as a debug trace (for example).  My example
implementation fails on this account, too.

-- David R. Tribble, dtribble@technologist.com --

      [ Send an empty e-mail to c++-help@netlab.cs.rpi.edu for info ]
      [ about comp.lang.c++.moderated. First time posters: do this! ]


[ 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: AllanW@my-dejanews.com
Date: 1998/11/12
Raw View
In article <3648DE67.3F87@noSPAM.central.beasys.com>,
  dtribble@technologist.com wrote:
 >
 > AllanW@my-dejanews.com wrote:
 > >> I compiled this code in MSVC5.0
 > >>     #include <iostream>
 > >>     class C { int x; };
 > >>     int main() {
 > >>         std::cout << typeid(::C).name() << std::endl;
 > >>         class C { float x; };
 > >>         std::cout << typeid(C).name() << std::endl;
 > >>         { class C { char *x; };
 > >>           std::cout << typeid(C).name() << std::endl; }
 > >>     }
 > >> The result was:
 > >>     class C
 > >>     class C
 > >>     class C
 > >> Would someone please confirm that this is NOT what was
 > >> supposed to happen?
 >
 > Paul D. DeRocco wrote:
 > > If you're expecting type_info::name() to return names that match what
 > > one would write in the source code, then the implementation did the
 > > "right" thing. If you're hoping for a unique name for every type, then
 > > obviously it did the "wrong" thing. However, it can't do both at the
 > > same time, in the presence of local names. It is only by within a
 > > single scope (e.g., global scope) that one can have valid
 > > source-code-matching names that are also guaranteed unique.
 >
 > True.  But it seems to me that in order to make type_info::name()
 > behave in the most reasonable fashion, typeid() ought to return a
 > unique string for every type in the program.
 >
 > And this isn't that hard to do.  Consider an implementation that
 > simply returns a string representation of the address of a type
 > "descriptor" in hexadecimal form:
 >
 >     cout << typeid(float).name();  // Prints "C0ED0040"
 >
 >     class C { ... };
 >     cout << typeid(C).name();      // Prints "C0EDB998"
 >
 >     {
 >         class C { ... };
 >         cout << typeid(C).name();  // Prints "C0EDBA72"
 >     }
 >
 >     {
 >         class C { ... };
 >         cout << typeid(C).name();  // Prints "C0EDBABE"
 >     }
 >
 > (No objects have to actually exist at the addresses printed, of
 > course.)
 >
 > I believe it's more useful for typeid().name() to return non-equal
 > names for truly non-like types, since I believe code that uses
 > typeid() is more likely to want to know when objects have different
 > types.  (Section 18.5.1 says nothing about type_info::operator=()
 > returning false if the types are different; that can be inferred,
 > but it's not explicitly stated.  Even less is guaranteed for
 > the result of type_info::name().)
 >
 > Of course, this might conflict with other people's views, e.g.,
 > that typeid().name() should return the same name for a given type
 > from one program execution to the next.  My example implementation
 > above doesn't necessarily guarantee this behavior.
 >
 > There's probably also the opinion that typeid().name() should return
 > a string that resembles the actual type name, so that it is useful
 > when printed as a debug trace (for example).  My example
 > implementation fails on this account, too.

What exactly is the purpose of name()?

I think that I at least half-expected name() to return something
intended for human readers. Something that would contain enough
information for a human reader to find the class in source files.
For instance,
    "C"             for the global class
    "main()::C"     for the local class
    "main()1::C"    for the nested local class
But if the standard doesn't say anything about this, then
clearly my expectations were too high.

What I wonder, now, is exactly what value name() has. Why is
it in the standard at all? If I knew it's purpose, my
expectations would be more reasonable.

--
AllanW@my-dejanews.com is a "Spam Magnet" -- never read.
Please reply in USENET only, sorry.

-----------== Posted via Deja News, The Discussion Network ==----------
http://www.dejanews.com/       Search, Read, Discuss, or Start Your Own
---
[ 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: icedancer.zamboni@ibm.zamboni.net (Ken Walter)
Date: 1998/11/12
Raw View
On Wed, 11 Nov 1998 16:54:52, David R Tribble
<david.tribble@noSPAM.central.beasys.com> wrote:

[...]
>
> True.  But it seems to me that in order to make type_info::name()
> behave in the most reasonable fashion, typeid() ought to return a
> unique string for every type in the program.
[...]
>
> Of course, this might conflict with other people's views, e.g.,
> that typeid().name() should return the same name for a given type
> from one program execution to the next.  My example implementation
> above doesn't necessarily guarantee this behavior.
[...]
And some will want it to work for a networked multi program system.
Problems like this were solved back in mainframe days for block
structured programs.

The type should be prefixed by all its enclosing scopes like:
 <Header File Name>::<Namespaces/Enclosing Classes>*::typeName.
Then two different programs using the same header on two different
CPUs
will have then same name for the same type.



Ken Walter

Remove .zamboni to reply
All the above is hearsay and the opinion of no one in particular



      [ Send an empty e-mail to c++-help@netlab.cs.rpi.edu for info ]
      [ about comp.lang.c++.moderated. First time posters: do this! ]
---
[ 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: AllanW@my-dejanews.com
Date: 1998/11/05
Raw View
In article <slrn6uodi9.ohq.sbnaran@localhost.localdomain>,
  sbnaran@KILL.uiuc.edu wrote:
> On 1 Nov 1998 10:31:22 -0500, Pete Becker <petebecker@acm.org> wrote:
> >void f()
> >{
> >class C {};
> >}
>
> [typeid(C).name()] should return "f()::C"
> If f() is in a namespace, this should return "namespace::f()::C".

I compiled this code in MSVC5.0
    #include <iostream>
    class C { int x; };
    int main() {
        std::cout << typeid(::C).name() << std::endl;
        class C { float x; };
        std::cout << typeid(C).name() << std::endl;
        { class C { char *x; };
          std::cout << typeid(C).name() << std::endl; }
    }
The result was:
    class C
    class C
    class C
Would someone please confirm that this is NOT what was
supposed to happen?

--
AllanW@my-dejanews.com is a "Spam Magnet" -- never read.
Please reply in USENET only, sorry.

-----------== Posted via Deja News, The Discussion Network ==----------
http://www.dejanews.com/       Search, Read, Discuss, or Start Your Own

      [ Send an empty e-mail to c++-help@netlab.cs.rpi.edu for info ]
      [ about comp.lang.c++.moderated. First time posters: do this! ]
---
[ 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: ncm@nospam.cantrip.org (Nathan Myers)
Date: 1998/11/05
Raw View
<AllanW@my-dejanews.com> wrote:
>I compiled this code on [...]
>    #include <iostream>
>    class C { int x; };
>    int main() {
>        std::cout << typeid(::C).name() << std::endl;
>        class C { float x; };
>        std::cout << typeid(C).name() << std::endl;
>        { class C { char *x; };
>          std::cout << typeid(C).name() << std::endl; }
>    }
>The result was:
>    class C
>    class C
>    class C
>Would someone please confirm that this is NOT what was
>supposed to happen?

It is *precisely* what is supposed to happen, on your compiler.
Here is all the standard says:

   const char* name() const;

   Returns: an implementation-defined NTBS.

An implementation is allowed to define name() to return the
empty string for all types.

If you don't like how your implementer defined it, your
only recourses are to (1) persuade them to define it more
to your liking, or (2) switch to a compiler you like better.

Perhaps the nicest definition would be one that lets you hook
in your own "remangler" (or one of theirs) at link-time.  I
suspect it will be a while before any implementer does that,
but any could add it any time.

--
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: sbnaran@localhost.localdomain.COM (Siemel Naran)
Date: 1998/11/06
Raw View
On 05 Nov 98 09:14:53 GMT, AllanW@my-dejanews.com
>  sbnaran@KILL.uiuc.edu wrote:

>> [typeid(C).name()] should return "f()::C"
>> If f() is in a namespace, this should return "namespace::f()::C".

>I compiled this code in MSVC5.0
>    #include <iostream>
>    class C { int x; };
>    int main() {
>        std::cout << typeid(::C).name() << std::endl;
>        class C { float x; };
>        std::cout << typeid(C).name() << std::endl;
>        { class C { char *x; };
>          std::cout << typeid(C).name() << std::endl; }
>    }
>The result was:
>    class C
>    class C
>    class C
>Would someone please confirm that this is NOT what was
>supposed to happen?

No, this is reasonable behaviour.  The string returned by typeid.name()
is not specified.

On EDG compilers, the global C is "C".
On EDG compilers, a C in an unnamed namespace is "<unnamed>::C".
On EDG compilers, the local C's are "C"
But I think it should be "main()::C" and "main(){}::C"


--
----------------------------------
Siemel B. Naran (sbnaran@uiuc.edu)
----------------------------------


      [ Send an empty e-mail to c++-help@netlab.cs.rpi.edu for info ]
      [ about comp.lang.c++.moderated. First time posters: do this! ]
---
[ 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: "Paul D. DeRocco" <pderocco@ix.netcom.com>
Date: 1998/11/06
Raw View
AllanW@my-dejanews.com wrote:
>
> I compiled this code in MSVC5.0
>     #include <iostream>
>     class C { int x; };
>     int main() {
>         std::cout << typeid(::C).name() << std::endl;
>         class C { float x; };
>         std::cout << typeid(C).name() << std::endl;
>         { class C { char *x; };
>           std::cout << typeid(C).name() << std::endl; }
>     }
> The result was:
>     class C
>     class C
>     class C
> Would someone please confirm that this is NOT what was
> supposed to happen?

If you're expecting type_info::name() to return names that match what
one would write in the source code, then the implementation did the
"right" thing. If you're hoping for a unique name for every type, then
obviously it did the "wrong" thing. However, it can't do both at the
same time, in the presence of local names. It is only by within a single
scope (e.g., global scope) that one can have valid source-code-matching
names that are also guaranteed unique.

--

Ciao,
Paul
---
[ 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: apjenkins@my-dejanews.com
Date: 1998/11/06
Raw View
In article <71q4cp$bdm$1@nnrp1.dejanews.com>,
  AllanW@my-dejanews.com wrote:
> In article <slrn6uodi9.ohq.sbnaran@localhost.localdomain>,
>   sbnaran@KILL.uiuc.edu wrote:
> > On 1 Nov 1998 10:31:22 -0500, Pete Becker <petebecker@acm.org> wrote:
> > >void f()
> > >{
> > >class C {};
> > >}
> >
> > [typeid(C).name()] should return "f()::C"
> > If f() is in a namespace, this should return "namespace::f()::C".
>
> I compiled this code in MSVC5.0
>     #include <iostream>
>     class C { int x; };
>     int main() {
>         std::cout << typeid(::C).name() << std::endl;
>         class C { float x; };
>         std::cout << typeid(C).name() << std::endl;
>         { class C { char *x; };
>           std::cout << typeid(C).name() << std::endl; }
>     }
> The result was:
>     class C
>     class C
>     class C
> Would someone please confirm that this is NOT what was
> supposed to happen?

Unfortunately this is allowed by the standard.  The only thing the standard
guarantees is that their typeid()s won't be equal as defined by
std::type_info::operator==.  type_info::name() is completely implementation
defined and can therefore be the same for more than one class.  As you can
gather by reading the rest of this thread, type_info::name() is quite useless
without additional implementation-specific guarantees beyond the standard.

That is:

#include <typeinfo>
#include <cassert>

class C {};

int main()
{
   class C {};
   assert(typeid(::C) != typeid(C));  // guaranteed by standard
   assert(typeid(::C).name() != typeid(C).name());  // not guaranteed
}

--
Adam P. Jenkins
ajenkins at javanet dot com

-----------== Posted via Deja News, The Discussion Network ==----------
http://www.dejanews.com/       Search, Read, Discuss, or Start Your Own
---
[ 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              ]