It is currently Sat Aug 08, 2020 8:20 pm


All times are UTC




Post new topic Reply to topic  [ 12 posts ]  Go to page 1, 2  Next
Author Message
 Post subject: [Resolved]: Integration fails compiling with VS2008
PostPosted: Thu Sep 01, 2011 8:23 pm 

Joined: Sun Jul 10, 2011 2:15 am
Posts: 12
The library itself builds fine, but LargeVolume can't be instantiated. In fact, LargeVolume.h can't even be included. The attempt causes an internal compiler error.

Here's the offending code from LargeVolumeSampler.inl:
Code:
template <typename VoxelType>
   LargeVolume<VoxelType>::Sampler::Sampler(LargeVolume<VoxelType>* volume)
      :Volume<VoxelType>::template Sampler< LargeVolume<VoxelType> >(volume)
   {
   }

The internal compiler error can be eliminated by modifying it to:
Code:
template <typename VoxelType>
   LargeVolume<VoxelType>::Sampler<VoxelType>::Sampler(LargeVolume<VoxelType>* volume)
      :Volume<VoxelType>::template Sampler< LargeVolume<VoxelType> >(volume)
   {
   }

But that version still doesn't compile. Here's the warnings and errors:
Code:
C:\Dev\polyvox\library\PolyVoxCore\include\PolyVoxCore/LargeVolumeSampler.inl(39) : warning C4346: 'PolyVox::LargeVolume<VoxelType>::Sampler' : dependent name is not a type
1>        prefix with 'typename' to indicate a type
1>C:\Dev\polyvox\library\PolyVoxCore\include\PolyVoxCore/LargeVolumeSampler.inl(39) : error C2143: syntax error : missing ';' before '<'
1>C:\Dev\polyvox\library\PolyVoxCore\include\PolyVoxCore/LargeVolumeSampler.inl(39) : error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>C:\Dev\polyvox\library\PolyVoxCore\include\PolyVoxCore/LargeVolumeSampler.inl(39) : error C2888: 'LargeVolume<VoxelType>::Sampler Sampler' : symbol cannot be defined within namespace 'PolyVox'
1>C:\Dev\polyvox\library\PolyVoxCore\include\PolyVoxCore/LargeVolumeSampler.inl(39) : fatal error C1903: unable to recover from previous error(s); stopping compilation

Following the advice of the warning has no effect. All five unprefixed occurrences of VoxelType can be prefixed with typename and the results are unchanged. Nested template class inheritance strangles VS2008, it would seem. Unfortunately I can't guess which type specifier it's having trouble with. (Removing the initializer entirely has no effect on the results either, incidentally.)

Little help?


Last edited by DragonM on Wed Sep 07, 2011 5:30 am, edited 1 time in total.

Top
Offline Profile  
Reply with quote  
 Post subject: Re: Integration fails compiling with Visual Studio 2008
PostPosted: Thu Sep 01, 2011 9:32 pm 
Developer
User avatar

Joined: Sun May 04, 2008 6:35 pm
Posts: 1827
I assume you are using the latest version from Git? Since the last snapshot I have been refactoring the code so the the various volume classes derive from a common base, and the use of nested templated inheritance has indeed caused a few headaches. The current code builds on both VS2010 and GCC, but I haven't tested other compilers.

Before we go any further, can you confirm whether the other volume classes cause the same problem (RawVolume and SimpleVolume)?


Top
Offline Profile  
Reply with quote  
 Post subject: Re: Integration fails compiling with Visual Studio 2008
PostPosted: Thu Sep 01, 2011 9:53 pm 
Developer
User avatar

Joined: Sun May 04, 2008 6:35 pm
Posts: 1827
DragonM wrote:
The internal compiler error can be eliminated by modifying it to:
Code:
template <typename VoxelType>
   LargeVolume<VoxelType>::Sampler<VoxelType>::Sampler(LargeVolume<VoxelType>* volume)
      :Volume<VoxelType>::template Sampler< LargeVolume<VoxelType> >(volume)
   {
   }


Actually I don't think you're fixing anything there. I tried the same change on VS2010 and it also gives compiler errors, which presumably the prevent the internal compiler error from occuring. Typing any invalid syntax would probably have the same effect.


Top
Offline Profile  
Reply with quote  
 Post subject: Re: Integration fails compiling with Visual Studio 2008
PostPosted: Thu Sep 01, 2011 9:56 pm 
Developer
User avatar

Joined: Sun May 04, 2008 6:35 pm
Posts: 1827
Also, I had to do a weird trick with typedef's to get it working on both VS2010 and GCC. Maybe it's relevent or you can do something similar:

Code:
class LargeVolume : public Volume<VoxelType>
   {
   public:
      typedef Volume<VoxelType> VolumeOfVoxelType; //Workaround for GCC/VS2010 differences. See http://goo.gl/qu1wn
      class Sampler : public VolumeOfVoxelType::template Sampler< LargeVolume<VoxelType> >


The webpagelinked from that comment also has a much simplified example which you could try in VS2008... might be a different problem though.


Top
Offline Profile  
Reply with quote  
 Post subject: Re: Integration fails compiling with Visual Studio 2008
PostPosted: Fri Sep 02, 2011 12:17 am 

Joined: Sun Jul 10, 2011 2:15 am
Posts: 12
David Williams wrote:
DragonM wrote:
The internal compiler error can be eliminated by modifying it to:
Code:
template <typename VoxelType>
   LargeVolume<VoxelType>::Sampler<VoxelType>::Sampler(LargeVolume<VoxelType>* volume)
      :Volume<VoxelType>::template Sampler< LargeVolume<VoxelType> >(volume)
   {
   }


Actually I don't think you're fixing anything there. I tried the same change on VS2010 and it also gives compiler errors, which presumably the prevent the internal compiler error from occuring. Typing any invalid syntax would probably have the same effect.
I got that modification from Microsoft's own documentation for Visual Studio 2010.
MSDN wrote:
Note that just as with any template class member function, the definition of the class's constructor member function includes the template argument list twice.
Of course, just because Microsoft says it's so doesn't make it so...


Top
Offline Profile  
Reply with quote  
 Post subject: Re: Integration fails compiling with Visual Studio 2008
PostPosted: Fri Sep 02, 2011 12:31 am 

Joined: Sun Jul 10, 2011 2:15 am
Posts: 12
David Williams wrote:
I assume you are using the latest version from Git? Since the last snapshot I have been refactoring the code so the the various volume classes derive from a common base, and the use of nested templated inheritance has indeed caused a few headaches. The current code builds on both VS2010 and GCC, but I haven't tested other compilers.

Before we go any further, can you confirm whether the other volume classes cause the same problem (RawVolume and SimpleVolume)?
Yes, latest Git.

Bizarrely, #including RawVolume.h and NOT including either ForwardDeclarations or LargeVolume.h, I get the LargeVolume Sampler errors reported in my first post (using my reported modification). No mention of RawVolume. Without my modification, I get an internal compiler error.

Same for SimpleVolume.


Top
Offline Profile  
Reply with quote  
 Post subject: Re: Integration fails compiling with Visual Studio 2008
PostPosted: Fri Sep 02, 2011 1:08 am 

Joined: Sun Jul 10, 2011 2:15 am
Posts: 12
David Williams wrote:
Also, I had to do a weird trick with typedef's to get it working on both VS2010 and GCC. Maybe it's relevent or you can do something similar:

Code:
class LargeVolume : public Volume<VoxelType>
   {
   public:
      typedef Volume<VoxelType> VolumeOfVoxelType; //Workaround for GCC/VS2010 differences. See http://goo.gl/qu1wn
      class Sampler : public VolumeOfVoxelType::template Sampler< LargeVolume<VoxelType> >


The webpagelinked from that comment also has a much simplified example which you could try in VS2008... might be a different problem though.

I did notice the typedef trick. If it's applicable, I fail to see how. Certainly creating typedef LargeVolume<VoxelType> LargeVolumeOfVoxelType and using it in either of the two possible locations in the code did me no good. The typedef can't be resolved as a class or namespace, so it fails to compile, for different reasons. Creating typedef Volume<VoxelType>::Sampler SamplerOfVoxelType has the same problem.

The C++ FAQ has a discussion of dependent and nondependent names. Unfortunately the sample doesn't appear to be applicable.

In my professional opinion, that thing you are doing, you shouldn't be doing. :ugeek: When two or more compilers can't parse the code in the same way, you run the risk that two or more compilers are going to fail to generate correct ASM. Writing code that's hard up against the bleeding edge of the language standard (or in your case, hanging over the bleeding edge waving your arms saying "Look at me, no hands!") means it's unlikely to be portable, generally usable code. Portable code is good practice. Unportable code usually means you're doing something you shouldn't.


Top
Offline Profile  
Reply with quote  
 Post subject: Re: Integration fails compiling with Visual Studio 2008
PostPosted: Fri Sep 02, 2011 9:57 pm 
Developer
User avatar

Joined: Sun May 04, 2008 6:35 pm
Posts: 1827
DragonM wrote:
Bizarrely, #including RawVolume.h and NOT including either ForwardDeclarations or LargeVolume.h, I get the LargeVolume Sampler errors reported in my first post (using my reported modification). No mention of RawVolume. Without my modification, I get an internal compiler error.


That sounds a little strange - I will try to find some time to test this for myself. I don't currently have VS2008 installed but can probably download the express version. However, I'm on a 5Gb/month download limit so I have to be a little careful. I think I can spare it though and it would be good to test.

DragonM wrote:
In my professional opinion, that thing you are doing, you shouldn't be doing. :ugeek: When two or more compilers can't parse the code in the same way, you run the risk that two or more compilers are going to fail to generate correct ASM. Writing code that's hard up against the bleeding edge of the language standard (or in your case, hanging over the bleeding edge waving your arms saying "Look at me, no hands!") means it's unlikely to be portable, generally usable code. Portable code is good practice. Unportable code usually means you're doing something you shouldn't.


I will freely admit that I'm pushing the compilers to the limit and also my own knowledge of template programming. Actually I've just been trying to see what I can do, and am aware of some issues which is why I haven't released a stable snapshot yet. That said, I do think the structure I'm aiming for makes sense so if it did compile more reliably that would be great :-)

I'll have a play with it and maybe relax a constraint. I'm not sure which one causes most problems out of 'nested', 'templated', or 'inherited' for these classes but I can probably remove the 'inherited' aspect most easily.

In the mean time, you can either use the last snapshot, or this version from Git which is from before I started this refactoring. I don't know how you check out a specific version from Git - you're on your own there :-) But it does include the VolumeResampler though the example is currently quite messy.


Top
Offline Profile  
Reply with quote  
 Post subject: Re: Integration fails compiling with Visual Studio 2008
PostPosted: Sat Sep 03, 2011 3:58 am 

Joined: Sun Jul 10, 2011 2:15 am
Posts: 12
David Williams wrote:
DragonM wrote:
Bizarrely, #including RawVolume.h and NOT including either ForwardDeclarations or LargeVolume.h, I get the LargeVolume Sampler errors reported in my first post (using my reported modification). No mention of RawVolume. Without my modification, I get an internal compiler error.


That sounds a little strange - I will try to find some time to test this for myself. I don't currently have VS2008 installed but can probably download the express version. However, I'm on a 5Gb/month download limit so I have to be a little careful. I think I can spare it though and it would be good to test.
I got more than one instance of peculiar behavior in that respect, including a successful build of LargeVolume<Material8> while Material.h wasn't included. It's apparently very easy to confuse VS2008 when dealing with complex templates.

David Williams wrote:
DragonM wrote:
In my professional opinion, that thing you are doing, you shouldn't be doing. :ugeek: When two or more compilers can't parse the code in the same way, you run the risk that two or more compilers are going to fail to generate correct ASM. Writing code that's hard up against the bleeding edge of the language standard (or in your case, hanging over the bleeding edge waving your arms saying "Look at me, no hands!") means it's unlikely to be portable, generally usable code. Portable code is good practice. Unportable code usually means you're doing something you shouldn't.


I will freely admit that I'm pushing the compilers to the limit and also my own knowledge of template programming. Actually I've just been trying to see what I can do, and am aware of some issues which is why I haven't released a stable snapshot yet. That said, I do think the structure I'm aiming for makes sense so if it did compile more reliably that would be great :-)

I'll have a play with it and maybe relax a constraint. I'm not sure which one causes most problems out of 'nested', 'templated', or 'inherited' for these classes but I can probably remove the 'inherited' aspect most easily.

In the mean time, you can either use the last snapshot, or this version from Git which is from before I started this refactoring. I don't know how you check out a specific version from Git - you're on your own there :-) But it does include the VolumeResampler though the example is currently quite messy.
'Inherited' appears to be causing most of the headaches. In the meantime, I switched to revision d327b88c1741768748855cdb8101396a0bd49faa, the one immediately after the one you linked to. That let me move on, anyway. Here's hoping you get something sorted out soon.


Top
Offline Profile  
Reply with quote  
 Post subject: Re: Integration fails compiling with Visual Studio 2008
PostPosted: Sat Sep 03, 2011 11:21 am 
Developer
User avatar

Joined: Sun May 04, 2008 6:35 pm
Posts: 1827
Ok, I've grabbed a copy of VS2008 Express (it was only 90mb) and done some investigation.

DragonM wrote:
David Williams wrote:
DragonM wrote:
Bizarrely, #including RawVolume.h and NOT including either ForwardDeclarations or LargeVolume.h, I get the LargeVolume Sampler errors reported in my first post (using my reported modification). No mention of RawVolume. Without my modification, I get an internal compiler error.


That sounds a little strange - I will try to find some time to test this for myself. I don't currently have VS2008 installed but can probably download the express version. However, I'm on a 5Gb/month download limit so I have to be a little careful. I think I can spare it though and it would be good to test.
I got more than one instance of peculiar behavior in that respect, including a successful build of LargeVolume<Material8> while Material.h wasn't included. It's apparently very easy to confuse VS2008 when dealing with complex templates.


This behaviour is (at least mostly) occuring because the #includes are a mess in the code. LargeVolume.h is included in a lot of places it shouldn't be. Actually I remember noticing this a few weeks ago when doing the volume refactoring, so I'll be sure to get it tidied up.

DragonM wrote:
The library itself builds fine, but LargeVolume can't be instantiated. In fact, LargeVolume.h can't even be included. The attempt causes an internal compiler error.


I managed to reproduce this quite easily, and it was fixed by removing some inheritance as previsouly suggested. However, I then noticed something interesting - when I checked out a fresh version of PolyVox and used CMake to generate the solution files it all compiled and ran perfectly, including the examples. However, the external test project was still giving an internal compiler error.

Eventually I started comparing compiler options and identified the '/Gm' switch as being the problem. This corresponds to 'Enabled Minimal Rebuild' and is on by default in a VS generated project but off in a CMake generated project. Removing this flag from the test project does seem to allow it to build correctly.

There is some chance that this issue is a result of the header file mess mentioned above. From the MSDN page:

MSDN wrote:
Minimal rebuild relies on class definitions not changing between include files. Class definitions must be global for a project (there should be only one definition of a given class), because the dependency information in the .idb file is created for the entire project. If you have more than one definition for a class in your project, disable minimal rebuild.


At any rate I think I should first sort out the header dependancies and then see whether this '/Gm' switch is still a problem.


Top
Offline Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 12 posts ]  Go to page 1, 2  Next

All times are UTC


Who is online

Users browsing this forum: No registered users and 2 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
cron
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
Theme created StylerBB.net