#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.
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?
Thanks for all insights!
Are you sure? I thought those live in something like
boost::bind::placeholders...
I agree with your interpretation. I really don't understand why the
Boost develoers put the placeholders into an unnamed namespace or gave
them internal linkage.
Cheers!
SG
Hm they would need to use "extern" declarations otherwise, and a .cpp file
where they define the placeholder. But they need/want to stay header-only.
> #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