Is it correct? Two same named classes in different unnamed namespaceget same typeid

Q

Qi

Let me show sample code to explain,

======================
Source file a.cpp (not header)

namespace {
class TestClass
{
int abc;
};
}

const std::type_info & getA()
{
return typeid(TestClass);
}


======================
Source file b.cpp (not header)

namespace {
class TestClass // same name as above class
{
// differ with another TestClass, so the type should be differ
long def;
};
}

const std::type_info & getB()
{
return typeid(TestClass);
}

======================

Tested in GCC 4.4.0 and 4.5.2, calling getA and getB, the
result is exactly same (== will return true).
So seems the RTTI for two TestClass are same.

I also tested in VC 2008, the typeid for both TestClass
are different, which is I expected.
However, seems previous VC also had that bug,
http://connect.microsoft.com/Visual...d-operator-on-instances-of-unnamed-class-type

Question:
Is it standard behavior, or undefined behavior, or a bug in GCC?

A further question:
Is it safe to use type_info to distinguish types?
i.e, different types (no matter in which namespace, which file),
will give different type_info?
The behavior in GCC really made me doubt that.


Thanks
 
J

Juha Nieminen

Qi said:
Let me show sample code to explain,

Explain what?

Since the dawn of usenet one of the core rules of proper posting is
that you don't post your question in the subject line and then just
allude to it in the body of the post. The actual contents of the post
should be understandable without the subject line. The subject line is
like a title, not the actual content. The post should be fully
understandable even without the subject line.

There are good reasons for this, even today. Subject lines might get
lost or mangled when usenet posts are automatically transferred to
other types of online communication, the screen space available to the
subject line might be limited, and so on.
 
Q

Qi

Explain what?

Since the dawn of usenet one of the core rules of proper posting is
that you don't post your question in the subject line and then just
allude to it in the body of the post. The actual contents of the post
should be understandable without the subject line. The subject line is
like a title, not the actual content. The post should be fully
understandable even without the subject line.

I would appreciate if you can scroll down your usenet
client to read my whole post.

======begin quote my post======
Question:
Is it standard behavior, or undefined behavior, or a bug in GCC?

A further question:
....more...
======end quote my post======

And with below paragraph
=====
Tested in GCC 4.4.0 and 4.5.2, calling getA and getB, the
result is exactly same (== will return true).
So seems the RTTI for two TestClass are same.
=====

Do you still not understand my question without the subject line?
 
T

Tom

In the example there is no polymorphic class type involved so we do
not have RTTI but static type information.

The standard states that type_info::eek:perator== should return true when
the type_info is for the same type. On the other hand it does not
state that the result is false for different types but probably this
is a bit a narrow-minded view. So I guess if you really refer to the
result of operator== then this probably is a compiler bug. If you have
simply looked on the name then things are different: The standard
explicitly says that the name is implementation depended. That's one
of the points about C++ I do not like. It would have been easy to
define a naming scheme. Then this name would be really useful, without
that type_info::name() is almost useless.

From my experience I recommend not to use typeid especially if you are
using namespaces. I think quite a lot of compilers have problems with
the same class name in different namespaces. Therefore you can be
quite sure to have problems sooner or later.
 
Q

Qi

In the example there is no polymorphic class type involved so we do
not have RTTI but static type information.

I think typeid is always static and compile time information.
So it has no connection with polymorphic.
Am I wrong?
From my experience I recommend not to use typeid especially if you are
using namespaces. I think quite a lot of compilers have problems with
the same class name in different namespaces. Therefore you can be
quite sure to have problems sooner or later.


Yup, that's my concern too.
So I will try to avoid typeid.

Thanks for the advice.
 
L

LR

Qi said:
I think typeid is always static and compile time information.
So it has no connection with polymorphic.
Am I wrong?

I didn't check the standard, but at least one compiler has this behavior:

#include <iostream>

class B {
public:
virtual ~B() {}
};
class D : public B {
public:
virtual ~D() {}
};
class F : public D {};

void f(const B &b) {
std::cout << typeid(b).name() << std::endl;
}

int main() {
f(B());
f(D());
f(F());
}

And the output is:
class B
class D
class F
Yup, that's my concern too.
So I will try to avoid typeid.

It will be interesting to see that problem interact with this new
feature: http://www2.research.att.com/~bs/C++0xFAQ.html#inline-namespace

LR
 
J

James Kanze

Let me show sample code to explain,
======================
Source file a.cpp (not header)
namespace {
class TestClass
{
int abc;
};
}
const std::type_info & getA()
{
return typeid(TestClass);
}
======================
Source file b.cpp (not header)
namespace {
class TestClass // same name as above class
{
// differ with another TestClass, so the type should be differ
long def;
};
}
const std::type_info & getB()
{
return typeid(TestClass);

}

Tested in GCC 4.4.0 and 4.5.2, calling getA and getB, the
result is exactly same (== will return true).
So seems the RTTI for two TestClass are same.

That surprises me very much. The two TestClass are two
different classes, because they are in two different namespaces.
(I don't have g++ installed on this machine to verify, but I do
remember doing some experiments with the uniqueness of
typeid(x).name(), and g++ generated different names for the two
different classes.)

How did you do your tests?
I also tested in VC 2008, the typeid for both TestClass
are different, which is I expected.
However, seems previous VC also had that bug,http://connect.microsoft.com/VisualStudio/feedback/details/100472/wro...
Question:
Is it standard behavior, or undefined behavior, or a bug in GCC?

Given that both classes are in an unnamed namespace, and they
are in different source files, they are unrelated classes, and
getA() may not be equal to getB().

If the classes weren't in unnamed namespace, you would have undefined
behavior (a violation of the one definition rule).
A further question:
Is it safe to use type_info to distinguish types?
i.e, different types (no matter in which namespace, which file),
will give different type_info?

Yes, although it's rarely useful.
The behavior in GCC really made me doubt that.

I'd want to see a copy/paste of the code, for all three files
(including the file with main which called getA() and getB()),
and the command line used to compile them, before I accept that
g++ is getting something this fundamental messed up. Especially
as I have seen g++ returning different values when calling
type_info::name in such cases.
 
L

LR

I snipped and pasted in the code I wrote. I didn't clean up any tabs
that might be in these, so it's possible you won't see the same thing I see.
#include <typeinfo>

namespace {
class TestClass
{
int abc;
};
}

const std::type_info & getA()
{
return typeid(TestClass);
}#include <typeinfo>
namespace {
class TestClass // same name as above class
{
// differ with another TestClass, so the type should be differ
long def;
};
}
const std::type_info & getB()
{
return typeid(TestClass);

}





My main.

#include <iostream>
#include <string>
#include <typeinfo>

const std::type_info & getB();
const std::type_info & getA();

std::string q(const std::type_info &t) {
return std::string("\"") + t.name() + "\"";

}

int main() {
std::cout << "A " << q(getA()) << std::endl;
std::cout << "B " << q(getB()) << std::endl;
return 0;
}
The output was:
A "N12_GLOBAL__N_19TestClassE"
B "N12_GLOBAL__N_19TestClassE"
I compiled using mingw gcc version 4.5.2 (GCC)
This is the command line for a.cpp, as reported by eclipse.
g++ -v -std=c++0x -O0 -g3 -Wall -c -fmessage-length=0 -o src\a.o
...\src\a.cpp


That surprises me very much. The two TestClass are two
different classes, because they are in two different namespaces.
(I don't have g++ installed on this machine to verify, but I do
remember doing some experiments with the uniqueness of
typeid(x).name(), and g++ generated different names for the two
different classes.)

How did you do your tests?

I tested very similar code in VS 2008 and got this result:
A "class `anonymous namespace'::TestClass"
B "class `anonymous namespace'::TestClass"
I'd want to see a copy/paste of the code, for all three files
(including the file with main which called getA() and getB()),
and the command line used to compile them, before I accept that
g++ is getting something this fundamental messed up. Especially
as I have seen g++ returning different values when calling
type_info::name in such cases.

Please see above.
 

Ask a Question

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

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

Ask a Question

Members online

Forum statistics

Threads
473,767
Messages
2,569,572
Members
45,046
Latest member
Gavizuho

Latest Threads

Top