Opened 15 years ago
Closed 14 years ago
#1711 closed Bugs (fixed)
Boost Serialization export facility broken on gcc 4.1, 4.2
Reported by: | Sohail Somani | Owned by: | Beman Dawes |
---|---|---|---|
Milestone: | Boost 1.36.0 | Component: | serialization |
Version: | Boost Development Trunk | Severity: | Showstopper |
Keywords: | Cc: | Robert Ramey |
Description
The test libs/serialization/test/test_exported.cpp fails on these compilers. However, if you reorder export.hpp to be after the inclusion of the archive headers, it works. Changing base_object to void_cast_register doesn't help either (since one is syntactic sugar for the other)
This shouldn't be the case as the header-ordering requirement is no longer there but it seems that the correct code is not being instantiated on this compiler. I cannot figure out why.
Please see this thread for further information: http://article.gmane.org/gmane.comp.lib.boost.devel/172421
If you need me to try any changes, let me know. I think this should be fixed for 1.35 because it essentially means that a very important part of the serialization lib does not work.
If we suggest the header-ordering workaround, I would really stress that we understand *why* this is happening.
Attachments (3)
Change History (31)
comment:1 by , 15 years ago
by , 15 years ago
Attachment: | weird.patch added |
---|
This patch shows which instantiation is causing the problem.
comment:3 by , 15 years ago
bjam gcc test_exported_text_archive
is passing for me in the Boost trunk with gcc 4.1.3 on ubuntu 7.10
Which test exactly is failing, please?
comment:4 by , 15 years ago
The reason the test is passing now is because Robert changed the header order to see if it would fix other failures.
comment:6 by , 15 years ago
OK, let me have a quick look at this. If it's a hard problem it's very unlikely I'll have time for a fix that would be accepted before 1.35 goes out, if a fix is even possible. If you're still of the opinion that the code shouldn't work on any compiler as written, could you please explain in a little more detail? It's been over a year since I've thought about how this stuff works.
Thanks.
follow-up: 8 comment:7 by , 15 years ago
I am not of the opinion that it shouldn't work on any compiler as written. I think it *should* work.
If you look at the patch that I've attached, it shows you which definition is affecting the ordering. I feel that it should work but when all the instantiation magic is happening, it is choosing the int overload rather than the Archive overload.
follow-up: 9 comment:8 by , 15 years ago
Replying to Sohail Somani <boost-trac@taggedtype.net>:
I feel that it should work but when all the instantiation magic is happening, it is choosing the int overload rather than the Archive overload.
The int overload of instantiate_ptr_serialization, that is.
follow-up: 10 comment:9 by , 15 years ago
Replying to Sohail Somani <boost-trac@taggedtype.net>:
Replying to Sohail Somani <boost-trac@taggedtype.net>:
I feel that it should work but when all the instantiation magic is happening, it is choosing the int overload rather than the Archive overload.
The int overload of instantiate_ptr_serialization, that is.
This is the case. If you remove the inlined empty definition of instantiate_ptr_serialization, there is a link error referencing the int instantiations. I think it is a g++ bug...
comment:10 by , 15 years ago
Replying to Sohail Somani <boost-trac@taggedtype.net>:
Replying to Sohail Somani <boost-trac@taggedtype.net>:
Replying to Sohail Somani <boost-trac@taggedtype.net>:
I feel that it should work but when all the instantiation magic is happening, it is choosing the int overload rather than the Archive overload.
The int overload of instantiate_ptr_serialization, that is.
This is the case. If you remove the inlined empty definition of instantiate_ptr_serialization, there is a link error referencing the int instantiations. I think it is a g++ bug...
That part at least isn't a surprise. As the comment says, that version of the function is actually called.
follow-up: 17 comment:11 by , 15 years ago
Oops... Is the int overload supposed to be called from guid_initializer<T>::export_guid?
The call to instantiate_ptr_serialization is a dependent lookup isn't it?
comment:12 by , 15 years ago
Uh... Is this version of g++ hopelessly broken?
From the standard (section 14.6.7) #include <iostream>
using namespace std;
void f(char){cout << "f(char)" << endl;} template<class T> void g(T t) {
f(1); f(char)
dependent
f(T(1));
dependent
f(t);
}
void f(int){cout << "f(int)" << endl;}
int main() {
will cause one call of f(char) followed
g(2);
by two calls of f(int) will cause three calls of f(char)
g('a');
}
comment:13 by , 15 years ago
Sorry my submit trigger finger went too early. Wow this is pretty messed up...
// From the standard (section 14.6.7) #include <iostream> using namespace std; void f(char){cout << "f(char)" << endl;} template<class T> void g(T t) { f(1); // f(char) f(T(1)); // dependent // dependent f(t); } void f(int){cout << "f(int)" << endl;} int main() { // will cause one call of f(char) followed g(2); // by two calls of f(int) // will cause three calls of f(char) g('a'); }
$ g++ /tmp/cpp.cpp -o /tmp/wtf_broken $ /tmp/wtf_broken f(char) f(char) f(char) f(char) f(char) f(char) $
by , 15 years ago
Attachment: | header_ordering_fix.patch added |
---|
Here is a fix which forces dependent name lookup and uses ADL to instantiate the appropriate classes. I am very doubtful that this will work on any other compiler since I haven't tried!
by , 15 years ago
Attachment: | header_ordering_fix.2.patch added |
---|
Doesn't use ADL. Don't know what I was thinking. Uses enable_if to instantiate the right stuff.
comment:16 by , 15 years ago
The patch doesn't seem to work for a few of the tests :-( Ambiguous overloads and stuff...
comment:17 by , 15 years ago
Replying to Sohail Somani <boost-trac@taggedtype.net>:
Oops... Is the int overload supposed to be called from guid_initializer<T>::export_guid?
The call to instantiate_ptr_serialization is a dependent lookup isn't it?
Yes, and yes.
See the comments at [browser:/trunk/boost/archive/detail/register_archive.hpp#L23] and [browser:/trunk/boost/archive/detail/register_archive.hpp#L29]. The problem, AFAICT, is that the 2nd overload there is not actually considered and thus its return type is never instantiated.
follow-up: 23 comment:18 by , 15 years ago
I'm wondering if this is the reason: http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/cwg_active.html#197
Since 14.6.4.2 temp.dep.candidate says that only Koenig lookup is done from the instantiation context, and since 3.4.2 basic.lookup.koenig says that fundamental types have no associated namespaces, either the example is incorrect (and f(int) will never be called) or the specification in 14.6.4.2 temp.dep.candidate is incorrect.
This gcc bug has a discussion about the above issue: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=2922
follow-up: 20 comment:19 by , 15 years ago
Resolution: | → fixed |
---|---|
Status: | new → closed |
comment:20 by , 15 years ago
Replying to dave:
Thanks for the inspiration, Sohail. in addition to being simpler, I believe this fix to be much, much safer than the attached patch; the chance of breaking another compiler by using it is next to nil. However, without your idea of forcing ADL I'm not sure it would have occurred to me.
follow-up: 24 comment:21 by , 15 years ago
Resolution: | fixed |
---|---|
Status: | closed → reopened |
comment:22 by , 15 years ago
Cc: | added |
---|---|
Owner: | changed from | to
Status: | reopened → new |
Reopening so Beman and Robert Ramey can decide together whether this is important enough to put in the 1.35 release.
comment:23 by , 15 years ago
Replying to Sohail Somani <boost-trac@taggedtype.net>:
I'm wondering if this is the reason: http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/cwg_active.html#197
Since 14.6.4.2 temp.dep.candidate says that only Koenig lookup is done from the instantiation context, and since 3.4.2 basic.lookup.koenig says that fundamental types have no associated namespaces, either the example is incorrect (and f(int) will never be called) or the specification in 14.6.4.2 temp.dep.candidate is incorrect.
Yes, I think you're right. Not having something in there to force ADL was my mistake. I'm a little surprised that I made it in the first place and also this worked anywhere before I made the patch. I guess my capacity to have issues with ADL is boundless ;-)
follow-up: 26 comment:24 by , 15 years ago
Replying to dave:
Sometimes you have to be thankful that there is something that so anally standard conforming (g++) and an expert like yourself to fix these issues. Anyway, I'm glad I could be a muse.
The previously failing test is now passing. One other thing is that you might want to do is to revert test_exported.cpp to its prior state (where export.hpp came before anything else.)
Would be great to have this rolled into a 1.35.0 re-release.
*nudge* *nudge* *wink* *wink*
:-)
follow-up: 27 comment:26 by , 15 years ago
Replying to Sohail Somani <boost-trac@taggedtype.net>:
The previously failing test is now passing. One other thing is that you might want to do is to revert test_exported.cpp to its prior state (where export.hpp came before anything else.)
See [43953]
comment:27 by , 15 years ago
Replying to dave:
Replying to Sohail Somani <boost-trac@taggedtype.net>:
The previously failing test is now passing. One other thing is that you might want to do is to revert test_exported.cpp to its prior state (where export.hpp came before anything else.)
See [43953]
Looks good. Thanks for looking into it.
I believe it fails on RC2 as well.