Opened 6 years ago
Last modified 5 years ago
#12243 new Bugs
Boost.Serialization compilation error in Visual Studio with Zc:wchar_t-
Reported by: | anonymous | Owned by: | Robert Ramey |
---|---|---|---|
Milestone: | To Be Determined | Component: | serialization |
Version: | Boost 1.61.0 | Severity: | Showstopper |
Keywords: | Cc: |
Description
The error is following:
C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\INCLUDE\limits(85) : error C2090: function returns array H:\Third_party_src\boost\boost_1_61_0-compiled\boost/archive/basic_text_oprimitive.hpp(147) : see reference to class template instantiation 'std::numeric_limits<_Ty>' being compiled with [ _Ty=const unsigned short [24] ] H:\Third_party_src\boost\boost_1_61_0-compiled\boost/archive/basic_text_oprimitive.hpp(180) : see reference to class template instantiation 'boost::archive::basic_text_oprimitive<OStream>::is_float<T>' being compiled with [ OStream=std::wostream, T=const unsigned short [24] ] H:\Third_party_src\boost\boost_1_61_0-compiled\boost/archive/xml_woarchive.hpp(73) : see reference to function template instantiation 'void boost::archive::basic_text_oprimitive<OStream>::save<const unsigned short[24]>(T (&))' being compiled with [ OStream=std::wostream, T=const unsigned short [24] ] H:\Third_party_src\boost\boost_1_61_0-compiled\boost/archive/xml_woarchive.hpp(73) : see reference to function template instantiation 'void boost::archive::basic_text_oprimitive<OStream>::save<const unsigned short[24]>(T (&))' being compiled with [ OStream=std::wostream, T=const unsigned short [24] ] H:\Third_party_src\boost\boost_1_61_0-compiled\boost/archive/impl/xml_woarchive_impl.ipp(144) : see reference to function template instantiation 'void boost::archive::xml_woarchive_impl<Archive>::save<const unsigned short[24]>(T (&))' being compiled with [ Archive=boost::archive::xml_woarchive, T=const unsigned short [24] ] ...............................
The problem is with boost/archive/impl/xml_woarchive_impl.ipp(144) line:
save(L"</boost_serialization>\n");
It's fixed by replacing line with
save((const wchar_t*)L"</boost_serialization>\n");
Interesting error, as it treats the literal L"</boost_serialization>\n" as 'const unsigned short [24]' and picks
template<class T> void save(const T & t){ basic_text_oprimitive<std::wostream>::save(t); }
from boost/archive/xml_woarchive.hpp , instead of correct
#ifndef BOOST_NO_INTRINSIC_WCHAR_T BOOST_WARCHIVE_DECL void save(const wchar_t * t); #endif
And... If we remove the
#ifndef BOOST_NO_INTRINSIC_WCHAR_T
everything (including /Zc:wchar_t and /Zc:wchar_t- configurations) compiles fine.
So the actual bug is this 'ifndef'.
Why it was placed here? Most likely by mistake.
Please remove this 'ifndef'.
Change History (6)
comment:1 by , 6 years ago
comment:2 by , 6 years ago
Component: | None → serialization |
---|---|
Owner: | set to |
comment:3 by , 6 years ago
could you expand a little on this? Where should the define go? I'm getting that there is no fix called for in the serialization library itself.
comment:4 by , 5 years ago
So the actual bug is this 'ifndef'.
Why it was placed here? Most likely by mistake.
nope - removing it will result in compile errors on platforms which don't define wchar_t
according to documentation on boost.config, BOOST_NO_CWCHAR is meant to indicate that the platform doesn't have headers for <wchar.h> and <cwchar> so that's not a great choice either
And... If we remove the
remove #ifndef BOOST_NO_INTRINSIC_WCHAR_T
everything (including /Zc:wchar_t and /Zc:wchar_t- configurations) compiles fine.
I can't see how this would actually work
comment:5 by , 5 years ago
I couldn't modify the bug description, so I placed additional info in the follow-up comment, so please read it.
In short, you should replace the uses of
#ifndef BOOST_NO_INTRINSIC_WCHAR_T
with
#ifndef BOOST_NO_CWCHAR
in several headers. (Othervise some functions for wchar_t will not be declared in /Zc:wchar_t- configuration.)
Such replacement would be consistent with other function declarations across boost, where type wchar_t is required (whether intrinsic of typedef'd). The macro BOOST_NO_INTRINSIC_WCHAR_T in these headers was used incorrectly, because the BOOST_NO_CWCHAR was actually meant.
The configuration /Zc:wchar_t- seems not to be properly tested in boost, as can be concluded from existence of this bug.
comment:6 by , 5 years ago
Sorry to confuse things but there are actually 3 distinct and completely orthogonal configuration macros here, and it appears serialization may need all 3:
BOOST_NO_INTRINSIC_WCHAR_T: Use when you are specializing a template or overloading a function on wchar_t as well as the other integer types. BOOST_NO_CWCHAR: Use before inclusion of <cwchar> or use of it's functions. BOOST_NO_STD_WSTRING: Use before use of std::wstring. Perversely, presence of this macro does not mean that you cannot at least forward declare basic_string<wchar_t>, but you may not be able to instantiate it (or it's members) without linker errors unless the user has specified some command-line magic. Or to put it another way, you can still use basic_string<wchar_t> in templates that will only be instantiated when actually used: in which situation the user gets what they deserve ;)
Note that the presence of one of these does not imply much if anything about the others - for example we have msvc with <cwchar> but wchar_t not a native type, while on gcc wchar_t is always a native type, even though the platform it's building for (early cygwin, some embedded platforms) has no wide character functions.
There is one final conundrum that only Robert can decide on - if wchar_t is not a distinct type, and integer and character types are to be handled differently, what is the library supposed to do exactly when presented with an unsigned short? We have no way of knowing whether it's a character or an integer. Special treatment for wchar_t* seems sensible though since there is no special overload for unsigned short*.
I'm not going to go through the whole codebase and suggest which should be used where (but let me know if you need help testing this specific configuration), but my suggestion would be:
load/save overloaded on wchar_t* : use BOOST_NO_CWCHAR, ditto in the implementation. load/save overloaded on wchar_t : maybe check for both BOOST_NO_INTRINSIC_WCHAR_T and BOOST_NO_CWCHAR.
HTH.
I searched the boost code a bit and came to conclusion that you should use
for functions that accept wchar_t literals.
Otherwise the function xml_woarchive_impl::save (and similar functions) won't work with wchar_t literals in Visual Studio with /Zc:wchar_t- .
The Boost.Serialization compilation error is a side effect of this oversight.