Jump to content


C++ and typedefs


13 replies to this topic

#1 Faelenor

    Member

  • Members
  • PipPip
  • 44 posts

Posted 06 September 2005 - 05:38 PM

Here is some code:

class A
{
};
 
class A2
{
};
 
class B : public A
{
private:
  typedef A super;
  typedef A2 not_super;
};
 
class C : public B
{
private:
  typedef B super;
 
public:
  void Method()
  {
    super::super  x;
    super::not_super y;
  }
};

I think that both lines of code in C::Method() shouldn't compile. In code warrior, this is the case, but in more complex classes, it seems that super::super is allowed! that's weird. In VC++, super::super compiles, but VC++ is not a reference...

Do you know if it should compile or not?

Thx,

-Francis

#2 Kippesoep

    New Member

  • Members
  • PipPip
  • 21 posts

Posted 06 September 2005 - 06:53 PM

It shouldn't compile with the typedefs being private in B. If they were public or protected, it should compile just fine.

#3 Faelenor

    Member

  • Members
  • PipPip
  • 44 posts

Posted 06 September 2005 - 07:51 PM

Yeah I know... It was a bad question. I mean, do you know why two compilers seem to have troubles or to be very permissive with this?

#4 tob

    New Member

  • Members
  • Pip
  • 9 posts

Posted 06 September 2005 - 10:26 PM

It's probably a standards support problem. gcc 3.3 outputs the following:

Quote

bla.cpp: In member function `void C::Method()':
bla.cpp:23: error: `typedef class A B::super' is private
bla.cpp:47: error: within this context
bla.cpp:25: error: `typedef class A2 B::not_super' is private
bla.cpp:49: error: within this context

Which version of VC++ do you use?
Support bacteria, it's the only culture some people have!

#5 .oisyn

    DevMaster Staff

  • Moderators
  • 1822 posts

Posted 07 September 2005 - 08:30 AM

VC++ 7.1 gives a compile error, as it should:
main.cpp(25) : error C2248: 'B::not_super' : cannot access private typedef declared in class 'B'
        main.cpp(13) : see declaration of 'B::not_super'
        main.cpp(9) : see declaration of 'B'

And, if you need a standard reference, use The online compiler of Comeau

.edit: never mind, I disabled language extensions, with these extensions enabled it compiles fine.
C++ addict
-
Currently working on: the 3D engine for Tomb Raider.

#6 Axel

    Valued Member

  • Members
  • PipPipPip
  • 119 posts

Posted 07 September 2005 - 10:23 AM

I don't think Comeau is more standard compliant than .NET 2003. It supports "the whole language" (it supports "export"), but that doesn't mean it has bugs too ;)

#7 .oisyn

    DevMaster Staff

  • Moderators
  • 1822 posts

Posted 07 September 2005 - 10:34 AM

Excuse me? :D
Comeau is definitely more standard compliant than VC++ 2003. That's because comeau strives to be standard compliant, and it will fix bugs on short notice if something turns out to be non-standard. VC++ doesn't claim to be standard compliant and it will definitely not try to accomplish that.

Furthermore, by many experts and even people in the committee, comeau is seen as -the- standard compliant compiler. Now that means something, in my opionion :)

And btw, export isn't the only difference between comean and VC++. For example, this compiles in VC++ while it shouldn't (why?)
struct A
{
	typedef int mytype;
	template<class T> struct mytemplate { };
};

template<class T> struct S
{
	void bla()
	{
 	T::mytype a;
 	T::mytemplate<int> b;
	}
};

Another example: this gives wrong results under VC++ (why?)
#include <iostream>

void func(char)
{
	std::cout << "func(char)" << std::endl;
}

template<class T> void tfunc(const T & t)
{
	func(t);
}

void func(int)
{
	std::cout << "func(int)" << std::endl;
}

int main()
{
	char c = 0;
	int i = 0;
	tfunc(c);
	tfunc(i);
}

C++ addict
-
Currently working on: the 3D engine for Tomb Raider.

#8 Faelenor

    Member

  • Members
  • PipPip
  • 44 posts

Posted 07 September 2005 - 11:14 AM

tob: I'm using VC++ 7.1

.oisyn: I know, this line doesn't compile on any compiler. But both lines shouldn't compile! So VC++ 7.1 is wrong, again!

Axel: VC++ 7.1 is indeed far from being bug free! (I hope that there was a missing "no" in your post).

#9 Kenneth Gorking

    Senior Member

  • Members
  • PipPipPipPip
  • 911 posts

Posted 08 September 2005 - 04:07 PM

Quote

For example, this compiles in VC++ while it shouldn't (why?)
Why shouldn't this compile?

Quote

Another example: this gives wrong results under VC++ (why?)
I got this:

func(char)
func(int)

Seems about right...
"Stupid bug! You go squish now!!" - Homer Simpson

#10 .oisyn

    DevMaster Staff

  • Moderators
  • 1822 posts

Posted 09 September 2005 - 07:33 AM

I was hoping someone would reply :wink:

Quote

Why shouldn't this compile?

T is a template type, you don't know what T::mytype is until you know the actual T. But the compiler needs to parse the template code before any template instantiation is done. So the standard dictates that the compiler should assume it's an identifier (function, variable, enum value, whatever) and not a type. You need to tell the compiler it's a typename using the typename keyword:
typename T::mytype a;

The same goes for the template, in my example it's obvious what it should be, but what if the template argument was a value instead of a type, like this:
T::mytemplate<3> b;
That could parse as a variable definition or a simple expression: test if the value of t::mytemplate is smaller than 3, and the result of that is smaller than b.
Therefore, next to the typename discussed earlier, you also need to specify a template:
typename T::template mytype<3> b;

Quote

Another example: this gives wrong results under VC++ (why?)
I got this:

func(char)
func(int)

Seems about right...

Wrong again, func(int) wasn't defined until after the definition of tfunc. Therefore, it shouldn't be considered in the list of possible overloads to call when tfunc calls func. func(char) should be called twice.
C++ addict
-
Currently working on: the 3D engine for Tomb Raider.

#11 bladder

    DevMaster Staff

  • Moderators
  • 1057 posts

Posted 09 September 2005 - 12:27 PM

Quote

Wrong again, func(int) wasn't defined until after the definition of tfunc. Therefore, it shouldn't be considered in the list of possible overloads to call when tfunc calls func. func(char) should be called twice.

intresting, I didn't know this one. Are you sure this is supposed to happen? Because tfunc *is* a template function, so it would technically be expanded at the time it was called, and at that time the compiler would know abou the func(int) function.

Also, in VC 7.1's defence it does state that it is 98 or 97% standards compliant or something, it doesnt state that it is 100% standards compliant.

Has anyone used the vc express products? Or does anyone have any idea about the level of standard compliancy in it?

#12 .oisyn

    DevMaster Staff

  • Moderators
  • 1822 posts

Posted 09 September 2005 - 01:54 PM

bladder said:

Quote

Wrong again, func(int) wasn't defined until after the definition of tfunc. Therefore, it shouldn't be considered in the list of possible overloads to call when tfunc calls func. func(char) should be called twice.

intresting, I didn't know this one. Are you sure this is supposed to happen? Because tfunc *is* a template function, so it would technically be expanded at the time it was called, and at that time the compiler would know abou the func(int) function.
It is actually in the MSDN documentation that VC++ doesn't behave according to the standard in that retrospect. Not that the docs point to paragraph 14.6.2 (dependent names) in the standard, while they in fact mean paragraph 14.6.3 (non-dependent names):

Quote

14.6.3 - Non-dependent names [temp.nondep]

-1- Non-dependent names used in a template definition are found using the usual name lookup and bound at the point they are used. [Example:

void g(double);
void h();

template<class T> class Z {
public:
	void f() {
  g(1);           //  calls  g(double)
  h++;            //  ill-formed: cannot increment function;
    //  this could be diagnosed either here or
    //  at the point of instantiation
	}
};

void g(int);                    //  not in scope at the point of the template
    //  definition, not considered for the call  g(1)

It's a bit weird though, this also means that a function like std::swap, which by default uses the assignment operator and a local temporary to make the swap for a custom type, shouldn't work for that type if it's not defined until after the definition of std::swap itself. But it works nevertheless. Comeau also reports the following:
template<class T> void tfunc(T t)
{
    func(t);
}

void func(int);

struct S { };
void func(S);

int main()
{
    int i = 4;
    S s;

    tfunc(i); // error: func(int) not declared at definition of tfunc
    tfunc(s); // this is fine
}
So for some reason, this rule only applies to primitive types. Well, I can guess the reason, if it also applies to user types template functions would be pretty useless, but why a different approach for primitives?

Quote

Also, in VC 7.1's defence it does state that it is 98 or 97% standards compliant or something, it doesnt state that it is 100% standards compliant.
Sure, and I think VC++ is a great compiler (since 7.1), I use it both for work (ok, not much choice there :wink:) and hobby. But saying comeau isn't any more compliant than VC++ is just a stab in the face of comeau :)

Quote

Has anyone used the vc express products? Or does anyone have any idea about the level of standard compliancy in it?

View Post

I tried VC++ 2005 express beta, hasn't changed a bit with regards to compliance. I do love C++/cli though, and that'll be my first entry point into .Net :)
C++ addict
-
Currently working on: the 3D engine for Tomb Raider.

#13 Kenneth Gorking

    Senior Member

  • Members
  • PipPipPipPip
  • 911 posts

Posted 10 September 2005 - 04:58 PM

.oisyn, you are assuming that the Microsoft compiler behaves according to the standards when it is compiling template classes/functions, which it doesn't. Hell, it doesn't even check the tempate classes/functions until they are used. A simple test:

template<class T> class TError
{
public:
	TError()
	{
  I Am an error
	}
};
This will compile just fine under VC7.1.

You may know your standards, but you don't know your compiler.
"Stupid bug! You go squish now!!" - Homer Simpson

#14 .oisyn

    DevMaster Staff

  • Moderators
  • 1822 posts

Posted 13 September 2005 - 07:32 AM

Quote

you are assuming that the Microsoft compiler behaves according to the standards when it is compiling template classes/functions, which it doesn't
Pardon me? I suggest you reread my post. I was talking about Comeau, and if you have read this thread thouroughly you'd know that I would never assume such a thing about the MSVC++ compiler ;)





1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users