Re: Is boost _N placeholders doing undefined behavior?
On Dec 22, 9:47 pm, "Johannes Schaub (litb)" <schaub-johan...@web.de>
wrote:
It looks to me as if the following header causes undefined
behavior when included multiple times in a program (in
different TUs):
#include <boost/bind.hpp>
inline void g(int a) { }
inline void f() {
int n = 0;
boost::bind(&g, _1)(n);
}
Do I misread the Standard? It appears to say that the
definition of "f" will cause undefined behavior by 3.2/5b2,
because the name "_1" will refer to different entities in each
definition of f.
If the name _1 resolves to different entities in different
translation units, then it's undefined behavior if you include
this code in more than one translation unit.
Note that this isn't the only case where the problem might pop
up. Consider:
#include <vector>
int const i = 42;
inline void f(std::vector<int>& v)
{
v.push_back(i);
}
Also undefined behavior (because I doesn't have external
linkage).
boost defines _1 using an unnamed namespace, and phoenix
defines _1 using internal linkage, both yielding to different
entities in different translation units. Will this cause any
practical problems with regard to the inline function? Could a
ODR-checking compiler (maybe one with link-time optimization)
give a diagnostic here?
I doubt that it will cause any problems unless the compiler is
specifically doing ODR checking (which no current compiler
does), and perhaps not even then; the compiler authors might
very well decide that ODR checking doesn't have to be perfect,
and e.g. simply compare an MD5 hash of the token sequence.
Still, it is undefined behavior, and it is rather sloppy of
someone like Boost to let it through.
--
James Kanze