
"Peder Holt" <peder.holt@gmail.com> wrote
On 6/2/05, Chris Uzdavinis <chris@uzdavinis.com> wrote:
1) The docs say that the BOOST_TYPEOF_INCREMENT_REGISTRATION_GROUP() macro is used in .hpp or .cpp files. I'm curious how it works in a .hpp file if that file is included in multiple .cpp files. Does it create a new group for the same types in each file?
Yes. That is where the basis for possible ODR violations arises. We have tried testing if this causes any problems for the compilers we support, but it seems to work ok.
A registration group is just a number. At the moment of registration we combine this number with __LINE__, thus getting a unique id for each type or template. A registration macro expands into a number of template specializations that help us to encode and decode the registered type/template (hence the requirement to specify it in the context of global namespace). In different translation units, depending on the order of #includs, the same types may have different ids, and so the same specializations -- different bodies. This is technically an ODR violation. To work this around, the encoding/decoding templates were placed into an unnamed namespace, so that they are different in different TUs, and not a subject to ODR. Unfortunately this doesn't fix the problem completely. Since typeof now relies on different templates in different TUs, it itself becomes a subject of ODR violation, if used in a header: TU1 struct A { typedef BOOST_TYPEOF(1 + 0.5) type; /*double*/ }; TU2 struct A { typedef BOOST_TYPEOF(1 + 0.5) type; /*also double, but calculated through different set of templates */ }; This issue was discussed at some point in the past. The decision was made to ignore this ODR violation, as long as compilers don't care. Fortunately, the compilers don't seem to care. We have a specific test that reproduces this situation as a part of our test rutine. Also, Martin Wille helped me to run this through como, strict mode, which is considered to be the strictest compiler around. Como didn't complain either. The only way to avoid the ODR violation seem to be to assign registration group numbers explicitly, and this would seriously reduce the usability of the library. Regards, Arkadiy