code compiles c++ 6.0, not in c++ .NET

S

Steve Richter

I am having a very hard time getting my 6.0 C++ template code to
compile on C++ .NET.

The following is one example of code that compiles in 6.0 but not in
..NET. Any ideas why?

-----------------------------------------
#include <list>

template <class A> class Cursor : public std::list<A>::iterator
{
void PosAfterActual( std::list<A>::iterator it ) ;
} ;

------------------------------------------------

Error message is:

c:\SrcomNet\TestTclass2.h(8) : warning C4346:
'std::list<_Ty>::iterator' : dependent name is not a type
prefix with 'typename' to indicate a type
c:\SrcomNet\TestTclass2.h(9) : see reference to class template
instantiation 'Cursor<A>' being compiled
c:\SrcomNet\TestTclass2.h(8) : error C2061: syntax error : identifier
'iterator'


Any help is very appreciated.

-Steve Richter
 
C

Carl Daniel [VC++ MVP]

Steve said:
I am having a very hard time getting my 6.0 C++ template code to
compile on C++ .NET.

The following is one example of code that compiles in 6.0 but not in
.NET. Any ideas why?

Because your code is not legal according to the C++ standard: a dependent
name is not a type unless prefixed with the typename keyword.
-----------------------------------------
#include <list>

template <class A> class Cursor : public std::list<A>::iterator
{
void PosAfterActual( std::list<A>::iterator it ) ;

void PosAfterActual( typename std::list said:
} ;

------------------------------------------------

Error message is:

c:\SrcomNet\TestTclass2.h(8) : warning C4346:
'std::list<_Ty>::iterator' : dependent name is not a type
prefix with 'typename' to indicate a type
c:\SrcomNet\TestTclass2.h(9) : see reference to class template
instantiation 'Cursor<A>' being compiled
c:\SrcomNet\TestTclass2.h(8) : error C2061: syntax error : identifier
'iterator'


Any help is very appreciated.

-cd
 
S

Steve Richter

Carl Daniel said:
Because your code is not legal according to the C++ standard: a dependent
name is not a type unless prefixed with the typename keyword.


void PosAfterActual( typename std::list<A>::iterator it );

What a language! Using it for 5 years and I still dont know what I am
doing.

This code, ok in 6.0, also did not compile in .NET:
HANDLE* pFile ;
vector<HANDLE> vec ;
vector<HANDLE>::iterator it ;
it = vec.begin( ) ;
pFile = it ;

it had to be changed to:
pFile = &(*it) ;

I dont like these changes. My code is windows specific, so portability
is a low priority. And the mods I have to make to my code appear to
make it less readable.

Does MS have a document that gets into the details of what was allowed
in VC++ 6.0 and is not in C++ .NET? I saw a migration guide on the
MSDN site, but it did not detail what I am running into.

thanks,

-Steve
 
C

Carl Daniel [VC++ MVP]

Steve said:
What a language! Using it for 5 years and I still dont know what I am
doing.

Yeah - 5 years after standardization, the people that wrote the standard are
still (actively!) discussing just exactly what the standard means. In
fairness to VC6 - the requirement for typename was added late in the
standardization process, after VC6 was already nearly shipping.
This code, ok in 6.0, also did not compile in .NET:
HANDLE* pFile ;
vector<HANDLE> vec ;
vector<HANDLE>::iterator it ;
it = vec.begin( ) ;
pFile = it ;

it had to be changed to:
pFile = &(*it) ;

This is due to library changes. Note that both implementations are
compliant with the standard - the standard simply doesn't say whether
vector<T>::iterator is a T* or not. In VC6, it is precisely a T*, in VC7
and above, it's a user defined class. Code like your pFile = it was never
guaranteed to work, whereas &*it is guaranteed to work.
I dont like these changes. My code is windows specific, so portability
is a low priority. And the mods I have to make to my code appear to
make it less readable.

In the case of &(*it), I'd have to agree, but then one could argue that you
shouldn't really be getting HANDLE*'s out of that vector anyway, but simply
using vector<HANDLE>::iterator. (And one could argue that that's nonesense
and you really need a HANDLE*, in which case you just have to pay for some
ugliness).
Does MS have a document that gets into the details of what was allowed
in VC++ 6.0 and is not in C++ .NET? I saw a migration guide on the
MSDN site, but it did not detail what I am running into.

I haven't seen anything that gets into this low level detail stuff. In
general, the changes in VC7 (and even more so, VC7.1) make the compiler much
closer to C++ standards conformance, so code that VC6 accepted that wasn't
quite standard conforming will frequently be kicked out by VC7{.1}.

-cd
 
H

Hendrik Schober

Steve Richter said:
[...]
This code, ok in 6.0, also did not compile in .NET:
HANDLE* pFile ;
vector<HANDLE> vec ;
vector<HANDLE>::iterator it ;
it = vec.begin( ) ;
pFile = it ;

it had to be changed to:
pFile = &(*it) ;

Right. Iterators aren't required to be plain
I dont like these changes. My code is windows specific, so portability
is a low priority. And the mods I have to make to my code appear to
make it less readable.

Even on Windows there are different compilers.
And you have different versions of the same
compiler. If they all accept std C++, porting
among them will be easier. That's why I think
making your code std conforming is worthwile.

In your specific case above, you could ask
yourself why you're using 'HANDLE*' at all,
instead of just using 'HANDLE'. Usually, when
using a pointer you indicate that there might
be a value (ptr!=0) or there might not (ptr==0).
With a handle, that seems unnecessary, since
there already is a value for an invalid handle.
Also, the 'HANDLE*' in the above code will
always refer to an 'HANDLE' object. And that's
what references were invented for.
So why don't you write it this

HANDLE pFile = *it ;

way? Unless there's a good reason for using a
pointer I would always prefer references.
Does MS have a document that gets into the details of what was allowed
in VC++ 6.0 and is not in C++ .NET? I saw a migration guide on the
MSDN site, but it did not detail what I am running into.

Basically, a lot of code that isn't standard
conforming and used to compile with VC6 won't
compile anymore. I'm not aware of a document
which lists all the differences.
(Note that the above cannot be blamed on VC6.
You were simply taking advantage of an
implementation detail of your std library.)
thanks,
HTH,

-Steve

Schobi

--
(e-mail address removed) is never read
I'm Schobi at suespammers org

"And why should I know better by now/When I'm old enough not to?"
Beth Orton
 
D

Dan Smith

Steve Richter said:
[...]
I dont like these changes. My code is windows specific, so portability
is a low priority. And the mods I have to make to my code appear to

You are using a language called C++ and Microsoft delivers a C++ compiler.
The code you wrote and VC6.0 compiled wasn't complaint with the C++
Standard. If Microsoft were to continue to support such code, it really
would be a new language say VC++6. Note that for a few easy things (e.g.,
"for" variable scoping), the compiler allows you to tweak C++ slightly.

Dan
 
S

Steve Richter

Hendrik Schober said:
Steve Richter said:
[...]
This code, ok in 6.0, also did not compile in .NET:
HANDLE* pFile ;
vector<HANDLE> vec ;
vector<HANDLE>::iterator it ;
it = vec.begin( ) ;
pFile = it ;

it had to be changed to:
pFile = &(*it) ;

Right. Iterators aren't required to be plain
pointers, even though for 'std::vector<>' that
is possible.

In your specific case above, you could ask
yourself why you're using 'HANDLE*' at all,
instead of just using 'HANDLE'. Usually, when
using a pointer you indicate that there might
be a value (ptr!=0) or there might not (ptr==0).
With a handle, that seems unnecessary, since
there already is a value for an invalid handle.
Also, the 'HANDLE*' in the above code will
always refer to an 'HANDLE' object. And that's
what references were invented for.
So why don't you write it this

HANDLE pFile = *it ;

the MsgWaitForMultipleObjects( ... ) api calls for a pointer to an
array of handles to be waited for. I wrapped that api with a version
that accepts a vector of handles:

namespace steve {
DWORD MsgWaitForMultipleObjects( const std::vector<HANDLE>& handles,
.... )
{
DWORD dwRc ;
const HANDLE* pHandles ;
int nHandleCx = handles.size( ) ;
pHandles = handles.Begin( ) ;
dwRc = ::MsgWaitForMultipleObjects( nHandleCx, (HANDLE*)pHandles,
.... ) ;
return dwRc ;
}
} ; // end namespace steve

That made it a little easier to call that api. Then I really went
wild and used vector<HANDLE> as a base class to a class that makes it
easier to build the vector of handles:
class vector_handles : public std::vector<HANDLE>
{
vector_handles( HANDLE h1 ) ;
vector_handles( HANDLE h1, HANDLE h2 ) ; // build vector with 2
handles.
vector_handles& operator<<( HANDLE hIn )
{ push_back( hIn ) ; return *this ; }
...
} ;

this class lets me call my version of MsgWait... like so:
steve::MsgWaitForMultipleObjects( vector_handles( hMutex, hThread
), ... ) ;
Basically, a lot of code that isn't standard
conforming and used to compile with VC6 won't
compile anymore. I'm not aware of a document
which lists all the differences.
(Note that the above cannot be blamed on VC6.
You were simply taking advantage of an
implementation detail of your std library.)

this NG is very good. thanks a lot.

-Steve
 
H

Hendrik Schober

Steve Richter said:
[...]
So why don't you write it this

HANDLE pFile = *it ;

the MsgWaitForMultipleObjects( ... ) api calls for a pointer to an
array of handles to be waited for. [...]

I see. Then you have the choice between
'&*v.begin()' or '&v[0]', which seem
equally bad at first. However, you will
get used to it.

Schobi

--
(e-mail address removed) is never read
I'm Schobi at suespammers org

"And why should I know better by now/When I'm old enough not to?"
Beth Orton
 
S

Steve Richter

Dan Smith said:
Steve Richter said:
[...]
I dont like these changes. My code is windows specific, so portability
is a low priority. And the mods I have to make to my code appear to

You are using a language called C++ and Microsoft delivers a C++ compiler.
The code you wrote and VC6.0 compiled wasn't complaint with the C++
Standard. If Microsoft were to continue to support such code, it really
would be a new language say VC++6. Note that for a few easy things (e.g.,
"for" variable scoping), the compiler allows you to tweak C++ slightly.

Hi Dan,

In practice, dont the standards stifle the development of the
language? When was a feature last added to C++?

Here are some additions I would like to see made to the language:
- #define scopable to a namespace
- ambiguous overload or base class - I would like to be able to tell
the compiler that a function or base class is prefered over
another.
- too much typing!
string* pName = new string ; // why must I type "string"
twice?
- C++ should fit in the managed world without having to be dumbed
down.
- built in reference counting
- pName = gc_new string ; // pName will be auto garbage
collected
- pName2 = pName ; // somehow incs a reference count.

Anyway. I dont intend my code to run on any platform other than
windows. I dont see how rigid standards benefit me at all.

-Steve
 
C

Carl Daniel [VC++ MVP]

Steve said:
Hi Dan,

In practice, dont the standards stifle the development of the
language? When was a feature last added to C++?

1998. Only a few months ago, was there finally a (one, uno) compiler
released that claims to actually implement the entire C++ standard.
Here are some additions I would like to see made to the language:
- #define scopable to a namespace

This is a common request.
- ambiguous overload or base class - I would like to be able to tell
the compiler that a function or base class is prefered over
another.
- too much typing!
string* pName = new string ; // why must I type "string"
twice?

You'll likely see something to address this (imagine how bad it is if the
type is significantly more complex than 'string') in the next rev of the C++
standard. See, for example,
http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/papers/2003/n1527.pdf, which
discusses one proposal to address this type of concern.
- C++ should fit in the managed world without having to be dumbed
down.
- built in reference counting
- pName = gc_new string ; // pName will be auto garbage
collected
- pName2 = pName ; // somehow incs a reference count.

Note that the managed world does not use reference counting, but Stay Tuned.
The desire for C++ to play well in the managed world is well known within
the VC team and in the industry at large (see e.g.
http://www.ecma-international.org/news/ecma-TG5-PR.htm). Expect to see
something in the future...

-cd
 
H

Hendrik Schober

Steve Richter said:
[...]
Hi Dan,

In practice, dont the standards stifle the development of the
language? When was a feature last added to C++?

This year with TR1. The features (AFAIK all
library enhancements) are supposed to become
part of the next standard (which cannot be
released before 2008).
Here are some additions I would like to see made to the language:
- #define scopable to a namespace

'inline', 'const'
[...]
- too much typing!
string* pName = new string ; // why must I type "string"
twice?

What about this
Base* p = new Derived;
then?
- C++ should fit in the managed world without having to be dumbed
down.

MC++ was created by one corporation. Shouldn't
it fit everybody's world then?
- built in reference counting

I wouldn't want to have the problems of
this. If you can live with them -- fine.
C++ allows us to have both and even more:
http://www.cuj.com/documents/s=7994/cujcexp1906alexandr/alexandr.htm
- pName = gc_new string ; // pName will be auto garbage
collected
- pName2 = pName ; // somehow incs a reference count.


That's spelled
boost::shared_ptr<string> pName( new string );
in C++.
(BTW, AFAIK, Boost's pointers are part of TR1
and should thus become members of the namespace
'std'.)
Anyway. I dont intend my code to run on any platform other than
windows. I dont see how rigid standards benefit me at all.

Windows already is a whole bunch of platforms.
And while you don't intend to port to anything
else, what about your boss? And what in five
years?
We have ported quite some code that never was
intended to get ported. The closer the code was
to the C++ std, the smaller the effort.

Schobi

--
(e-mail address removed) is never read
I'm Schobi at suespammers org

"And why should I know better by now/When I'm old enough not to?"
Beth Orton
 
D

Dan Smith

I'm not trying to claim (right now) that you benefit from Standard C++ (you
do, but that's a different discussion).

Rather, the language that VC6.0 compiled really wasn't C++, let's call it
instead VCPP6. Just like C++ has a lot in common with C, VCPP6 has at lot
in common with C++, but as your code illustrates they aren't the same
language. Since I think there is only one compiler that is fully Standard
C++ compliant (EDG), the same thing can be said for VC7.0 and VC7.1. The
difference is that VCPP71 is a lot closer to Standard C++ than VCPP6.

So, just how many different C++-like languages should Microsoft support?
And what should that support entail? Should VCPP6 have managed extensions
too? It's hard enough to just implement Standard C++; I'm sure that
supportting VCPP6 in Visual Studio 2003 would be a lot of work.

Dan

Steve Richter said:
"Dan Smith" <[email protected]> wrote in message
Steve Richter said:
[...]
I dont like these changes. My code is windows specific, so portability
is a low priority. And the mods I have to make to my code appear to

You are using a language called C++ and Microsoft delivers a C++ compiler.
The code you wrote and VC6.0 compiled wasn't complaint with the C++
Standard. If Microsoft were to continue to support such code, it really
would be a new language say VC++6. Note that for a few easy things (e.g.,
"for" variable scoping), the compiler allows you to tweak C++ slightly.

Hi Dan,

In practice, dont the standards stifle the development of the
language? When was a feature last added to C++?

Here are some additions I would like to see made to the language:
- #define scopable to a namespace
- ambiguous overload or base class - I would like to be able to tell
the compiler that a function or base class is prefered over
another.
- too much typing!
string* pName = new string ; // why must I type "string"
twice?
- C++ should fit in the managed world without having to be dumbed
down.
- built in reference counting
- pName = gc_new string ; // pName will be auto garbage
collected
- pName2 = pName ; // somehow incs a reference count.

Anyway. I dont intend my code to run on any platform other than
windows. I dont see how rigid standards benefit me at all.

-Steve
 
S

Steve Richter

Dan Smith said:
I'm not trying to claim (right now) that you benefit from Standard C++ (you
do, but that's a different discussion).

Rather, the language that VC6.0 compiled really wasn't C++, let's call it
instead VCPP6. Just like C++ has a lot in common with C, VCPP6 has at lot
in common with C++, but as your code illustrates they aren't the same
language. Since I think there is only one compiler that is fully Standard
C++ compliant (EDG), the same thing can be said for VC7.0 and VC7.1. The
difference is that VCPP71 is a lot closer to Standard C++ than VCPP6.

So, just how many different C++-like languages should Microsoft support?
And what should that support entail? Should VCPP6 have managed extensions
too? It's hard enough to just implement Standard C++; I'm sure that
supportting VCPP6 in Visual Studio 2003 would be a lot of work.

Dan

Yeah I guess so. No problem. I really appreciate the feedback from
all and have ordered the Alexandrescu book:

http://www.amazon.com/exec/obidos/tg/detail/-/0201704315/002-0265981-9979277?v=glance

-Steve
 
G

Guest

Steve,

Yes, I have been using C++ for 9 years now.
Basically the newer VC 7.1 compiler follows the C++
standard much better. This would be the same if you where
gnu gcc 3+ versions or other compilers.

Unfortunately Kai c++ is no longer or was taken over by
Intel so there is no more Solaris support there for the
newest version.
Kai C++ used to be the best compiler for following the
standard and giving you great error messages.

Lars Schouw
 
H

Hendrik Schober

[...]
Kai C++ used to be the best compiler for following the
standard and giving you great error messages.

It seems as if Comeau has got this reputation
now: www.comeaucomputing.com.
Lars Schouw

Schobi

--
(e-mail address removed) is never read
I'm Schobi at suespammers org

"And why should I know better by now/When I'm old enough not to?"
Beth Orton
 

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

Top