boost::typeof, MSVC7.1 & 8.0, and precompiled headers

Hello to all, I just wanted to let you know that boost::typeof doesn't work (in today CVS) when included in a precompiled header with recent MSVC, because of a (seemingly common in other boost libs) anonymous-namespace error. I'm waiting for boost::typeof to work like a charm in MSVC8 so that I can ditch the evil-hack MSVC7 typeof implementation and migrate to MSVC8 :) Thanks, Bertrand PS : Arkadiy, I took the liberty to CC you because you were the one who pointed me to boost::typeof on clc++m and you seem to be in charge for this :)

"Bertrand Augereau" <bertrand@eugensystems.com> wrote
I just wanted to let you know that boost::typeof doesn't work (in today CVS) when included in a precompiled header with recent MSVC, because of a (seemingly common in other boost libs) anonymous-namespace error. I'm waiting for boost::typeof to work like a charm in MSVC8 so that I can ditch the evil-hack MSVC7 typeof implementation and migrate to MSVC8 :)
I guess the problem happens when you put typeof.hpp in the precompiled header, and then trying to register additional types outside this precompiled header... Typeof was moved into unnamed namespace to avoid ODR violation when using from cpp files (this doesn't help when using typeof in the headers, though). Does anybody have any experience in specializing templates, defined in unnamed namespace, in conjunction with precompiled headers? Specifically if the main template is defined in the precompiled header (in unnamed namespace), and then is specialized outside it? Is this supposed to work? I would assume it is -- precompiled headers are supposed to be transparent, aren't they? Thanks in advance for any help. Regards, Arkadiy

"Arkadiy Vertleyb" <vertleyb@hotmail.com> wrote
"Bertrand Augereau" <bertrand@eugensystems.com> wrote
I just wanted to let you know that boost::typeof doesn't work (in today CVS) when included in a precompiled header with recent MSVC, because of a (seemingly common in other boost libs) anonymous-namespace error. I'm waiting for boost::typeof to work like a charm in MSVC8 so that I can ditch the evil-hack MSVC7 typeof implementation and migrate to MSVC8 :)
I guess the problem happens when you put typeof.hpp in the precompiled header, and then trying to register additional types outside this precompiled header...
Hmmm.... It looks like it may be possible to workaround the precompiled heades problem by using "unnamed::boost::typeof" instead of "boost::typeof::unnamed" (vc7.1 at least seems to handle this much better). We would have to violate the Boost namespace naming convention though :( Regards, Arkadiy

Just wanted to confirm it works fully on our project with VC7.1 with typeof emulation and precompiled headers (at last I can cvs up and test with the new CVS setup :) ) Seems we have trouble with VC8.0 though, I'll test further and get back to you. Thanks, Bertrand

Argh... The following snippet doesn't compile on MSVC8.0 if stdafx.h (the precompiled header) includes "boost\typeof\typeof.hpp", and works if not... (The project is otherwise a default-settings console app) #include "stdafx.h" #include "boost\typeof\typeof.hpp" #include BOOST_TYPEOF_INCREMENT_REGISTRATION_GROUP() class Class {}; BOOST_TYPEOF_REGISTER_TYPE(Class) int _tmain(int argc, _TCHAR* argv[]) { return 0; } and it dumps these (quite meaningless) errors: error C2143: syntax error : missing ';' before '<' error C2059: syntax error : '<' error C2065: 'V' : undeclared identifier error C2143: syntax error : missing ';' before '{' error C2447: '{' : missing function header (old-style formal list?) error C2143: syntax error : missing ';' before '<' error C2059: syntax error : '<' error C2143: syntax error : missing ';' before '{' error C2447: '{' : missing function header (old-style formal list?) Maybe you can save me, once again, Arkadiy? :) Cheers, Bertrand

"Bertrand Augereau" <bertrand@eugensystems.com> wrote
Argh... The following snippet doesn't compile on MSVC8.0 if stdafx.h (the precompiled header) includes "boost\typeof\typeof.hpp", and works if not... (The project is otherwise a default-settings console app)
#include "stdafx.h" #include "boost\typeof\typeof.hpp"
#include BOOST_TYPEOF_INCREMENT_REGISTRATION_GROUP()
class Class {};
BOOST_TYPEOF_REGISTER_TYPE(Class)
int _tmain(int argc, _TCHAR* argv[]) { return 0; }
and it dumps these (quite meaningless) errors: error C2143: syntax error : missing ';' before '<' error C2059: syntax error : '<' error C2065: 'V' : undeclared identifier error C2143: syntax error : missing ';' before '{' error C2447: '{' : missing function header (old-style formal list?) error C2143: syntax error : missing ';' before '<' error C2059: syntax error : '<' error C2143: syntax error : missing ';' before '{' error C2447: '{' : missing function header (old-style formal list?)
Maybe you can save me, once again, Arkadiy? :)
This looks like something is undefined... Unfortunately, the vc8 beta period is over, and all of a sudden I no longer have an access too this compiler :( I'll see what I can do to get it... Meanwhile, is there anybody with the access to vc8 who is willing to help? Thanks in advance, Arkadiy

Arkadiy Vertleyb wrote:
This looks like something is undefined...
Unfortunately, the vc8 beta period is over, and all of a sudden I no longer have an access too this compiler :( I'll see what I can do to get it... Meanwhile, is there anybody with the access to vc8 who is willing to help?
Thanks in advance, Arkadiy
I'd like to, I even tried to browse the preprocessing, to some extent, but I lack too much insight about this kind of tricky metaprogramming :( (By the way you probably can download for free the express edition : http://msdn.microsoft.com/vstudio/express/visualc/ ) Cheers, Bertrand

"Bertrand Augereau" <bertrand@eugensystems.com> wrote
Arkadiy Vertleyb wrote:
This looks like something is undefined...
Unfortunately, the vc8 beta period is over, and all of a sudden I no longer have an access too this compiler :( I'll see what I can do to get it... Meanwhile, is there anybody with the access to vc8 who is willing to help?
Thanks in advance, Arkadiy
I'd like to, I even tried to browse the preprocessing, to some extent, but I lack too much insight about this kind of tricky metaprogramming :( (By the way you probably can download for free the express edition : http://msdn.microsoft.com/vstudio/express/visualc/ )
Yes, thanks, that's what I did. Now I need to fix my Boost CVS view (should be able to do it tonight), and then I'll be able to look at this... Regards, Arkadiy

On 5/31/06, Arkadiy Vertleyb <vertleyb@hotmail.com> wrote:
"Bertrand Augereau" <bertrand@eugensystems.com> wrote
Argh... The following snippet doesn't compile on MSVC8.0 if stdafx.h (the precompiled header) includes "boost\typeof\typeof.hpp", and works if not... (The project is otherwise a default-settings console app)
#include "stdafx.h" #include "boost\typeof\typeof.hpp"
#include BOOST_TYPEOF_INCREMENT_REGISTRATION_GROUP()
class Class {};
BOOST_TYPEOF_REGISTER_TYPE(Class)
int _tmain(int argc, _TCHAR* argv[]) { return 0; }
and it dumps these (quite meaningless) errors: error C2143: syntax error : missing ';' before '<' error C2059: syntax error : '<' error C2065: 'V' : undeclared identifier error C2143: syntax error : missing ';' before '{' error C2447: '{' : missing function header (old-style formal list?) error C2143: syntax error : missing ';' before '<' error C2059: syntax error : '<' error C2143: syntax error : missing ';' before '{' error C2447: '{' : missing function header (old-style formal list?)
Maybe you can save me, once again, Arkadiy? :)
This looks like something is undefined...
Unfortunately, the vc8 beta period is over, and all of a sudden I no longer have an access too this compiler :( I'll see what I can do to get it... Meanwhile, is there anybody with the access to vc8 who is willing to help?
I tried compiling the test battery on VC8 with precompiled headers enabled (\Yc with test.hpp as the precompiled header) and encountered similar problems. Eliminating the anonymous namespaces solves the problem, and doesn't introduce any obvious new problems. Is there more than a theoretical reason for the anonymous namespaces in the first place? Is there any observed cases where not having anonymous namespaces causes corruption to typeof? Regards, Peder
Thanks in advance, Arkadiy
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

"Peder Holt" <peder.holt@gmail.com> wrote
I tried compiling the test battery on VC8 with precompiled headers enabled (\Yc with test.hpp as the precompiled header) and encountered similar problems. Eliminating the anonymous namespaces solves the problem, and doesn't introduce any obvious new problems. Is there more than a theoretical reason for the anonymous namespaces in the first place? Is there any observed cases where not having anonymous namespaces causes corruption to typeof?
There are no observed cases, AFAIK. However, there is also not a lot of experience. ODR is definitely violated, one way or another. Compilers don't seem to complain about our ODR test, but this test is designed for anonymous namespaces. I can also imagine that some compilers may report ODR violation only in certain context. And we never know what new [versions of] compilers will do. It's easy to make the usage of anonymous namespace configurable by introducing something like BOOST_TYPEOF_SUPRESS_UNNAMED_NAMESPACE. I would also add another ODR test, targeted to this mode. Having two possibilities may give a better chance of avoiding potential issues with ODR. And having the mode without unnamed namespace would also allow the user to completely avoid ODR by always registering in the same order (having system-wide registration header), although at the expence of dependency bottleneck. Does this make sence? Regards, Arkadiy

On 6/9/06, Arkadiy Vertleyb <vertleyb@hotmail.com> wrote:
"Peder Holt" <peder.holt@gmail.com> wrote
I tried compiling the test battery on VC8 with precompiled headers enabled (\Yc with test.hpp as the precompiled header) and encountered similar problems. Eliminating the anonymous namespaces solves the problem, and doesn't introduce any obvious new problems. Is there more than a theoretical reason for the anonymous namespaces in the first place? Is there any observed cases where not having anonymous namespaces causes corruption to typeof?
There are no observed cases, AFAIK.
However, there is also not a lot of experience. ODR is definitely violated, one way or another. Compilers don't seem to complain about our ODR test, but this test is designed for anonymous namespaces. I can also imagine that some compilers may report ODR violation only in certain context. And we never know what new [versions of] compilers will do.
It's easy to make the usage of anonymous namespace configurable by introducing something like BOOST_TYPEOF_SUPRESS_UNNAMED_NAMESPACE. I would also add another ODR test, targeted to this mode.
Having two possibilities may give a better chance of avoiding potential issues with ODR. And having the mode without unnamed namespace would also allow the user to completely avoid ODR by always registering in the same order (having system-wide registration header), although at the expence of dependency bottleneck.
Does this make sence?
Makes sense. A good test then would be: File 1 #include <boost/typeof.hpp> #include <type_registration1.hpp> #include <type_registration2.hpp> Use TYPEOF on types registered in type_registrationx.hpp File 2 #include <boost/typeof.hpp> #include <type_registration2.hpp> #include <type_registration1.hpp> Use TYPEOF on types registered in type_registrationx.hpp We should probably disable anonymous namespaces by default when using precompiled headers. Is there a #define to check if precompiled headers is used? Regards, Peder
Regards, Arkadiy
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

"Peder Holt" <peder.holt@gmail.com> wrote
We should probably disable anonymous namespaces by default when using precompiled headers.
I am not sure -- typeof doesn't have to be included in PCH.... The reason I am more comfortable with unnamed namespace is bind placeholders. They are defined in unnamed namespace, and have been around for quite some time apparently without causing any ODR problems. Regards, Arkadiy

"Bertrand Augereau" <bertrand@eugensystems.com> wrote
The following snippet doesn't compile on MSVC8.0 if stdafx.h (the precompiled header) includes "boost\typeof\typeof.hpp", and works if not... (The project is otherwise a default-settings console app)
#include "stdafx.h" #include "boost\typeof\typeof.hpp"
#include BOOST_TYPEOF_INCREMENT_REGISTRATION_GROUP()
class Class {};
BOOST_TYPEOF_REGISTER_TYPE(Class)
int _tmain(int argc, _TCHAR* argv[]) { return 0; }
and it dumps these (quite meaningless) errors: error C2143: syntax error : missing ';' before '<' error C2059: syntax error : '<' error C2065: 'V' : undeclared identifier error C2143: syntax error : missing ';' before '{' error C2447: '{' : missing function header (old-style formal list?) error C2143: syntax error : missing ';' before '<' error C2059: syntax error : '<' error C2143: syntax error : missing ';' before '{' error C2447: '{' : missing function header (old-style formal list?)
This is the same problem that was worked around (by re-defining unnamed namespace) some time ago. The main template is defined inside unnamed namespace, and this definition is put into PCH. The template is specialized outside PCH. Since this is done in another TU, the unnamed namespace is different, and the system can't match the template and the specialization. The workaround works for VC71 and, I am pretty sure it worked for VC80 beta. Unfortunately it doesn't seem to work for VC80 express :( I believe this is a bug in the compiler, since the use of PCH should be transparent. The fact that PCH is created when another TU is compiled is an implementation detail, and should not prevent legal C++ code from being compiled (anybody knows if it's possible to report bugs to Microsoft?). Meanwhile, the only solution that I can see, is to get rid of the unnamed namespace. This could increase number of contexts where ODR violation happens. The compilers may or may not care. It's possible to make it configurable by indroducing some define, like BOOST_TYPEOF_SUPRESS_UNNAMED_NAMESPACE or similar. OTOH, getting rid of unnamed namespace could make it possible for the users to avoid ODR violations altogether (if they want to), by always registering types in the same order. This, of course, would be done at the expence of introducing a dependency bottleneck :( Thoughts? Regards, Arkadiy

This is the same problem that was worked around (by re-defining unnamed namespace) some time ago. The main template is defined inside unnamed namespace, and this definition is put into PCH. The template is specialized outside PCH. Since this is done in another TU, the unnamed namespace is different, and the system can't match the template and the specialization.
The workaround works for VC71 and, I am pretty sure it worked for VC80 beta. Unfortunately it doesn't seem to work for VC80 express :(
I believe this is a bug in the compiler, since the use of PCH should be transparent. The fact that PCH is created when another TU is compiled is an implementation detail, and should not prevent legal C++ code from being compiled (anybody knows if it's possible to report bugs to Microsoft?).
http://lab.msdn.microsoft.com/productfeedback/ seems to be the place to do such a thing (never done it myself). I can find no reference to this bug of bad unnamed namespace/PCH interaction yet, so maybe we are the first ones to notice such a thing.

(anybody knows if it's possible to report bugs to Microsoft?)
http://lab.msdn.microsoft.com/productfeedback/ , but you'll have to go through about 700 forms if you're not already a msdn member. Stephen
participants (4)
-
Arkadiy Vertleyb
-
Bertrand Augereau
-
Peder Holt
-
Stephen Dolan