
On 5/4/2011 4:23 AM, John Bytheway wrote:
On 03/05/11 21:28, Matthew Chambers wrote: <snip>
I use an optional header that defines lexical_cast string->numeric specializations using strto[ld]. Is this at risk for ODR violations? I use it widely but I'm not at all careful about making sure it's included everywhere. Yet I haven't had any ODR violations on GCC or MSVC. Unless that's pure luck, I'd like to know how the optional specializations are ODR violations.
[...snip simple and effective explanation...]
$ g++ -o odr main.cpp f.cpp g.cpp $ ./odr <i at 0x7fff0d49ef8c> <i at 0x7fff0d49ef8c> $ g++ -o odr main.cpp g.cpp f.cpp $ ./odr int(0) int(0)
It does different things according the the order in which I pass the source files on the command line. This is because the two (different) definitions of print<int> are being merged into one.
There may or may not be a second ODR violation because of the two different definitions of print_helper<int>. My standard-ese is insufficient to figure out whether this is a violation or not.
But even this first problem could clearly arise if e.g. library A which uses Boost.Convert in a template function to perform a conversion which is specialised by library B which depends on library A. This is very difficult to detect and avoid.
You make me cry sir. I'll file this under "ways that C++ assists your process to commit suicide". Cross-referenced with "ways that C++ causes programmer neuroses." I agree that boost shouldn't provide optional template specializations. So in a single binary, only one definition for lexical_cast<int, string> is allowed? Through "luck" it seems my optimized specializations have been overriding the stringstream ones, but it makes me cringe now. Maybe it even causes some mysterious crashes I've had in my C++/CLI bindings. Thanks, -Matt