Is boost _N placeholders doing undefined behavior?

  • Thread starter Johannes Schaub (litb)
  • Start date
J

Johannes Schaub (litb)

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.

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!
 
B

Balog Pal

Johannes Schaub (litb) said:
#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

Are you sure? I thought those live in something like
boost::bind::placeholders...
 
S

SG

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.

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
 
J

Johannes Schaub (litb)

SG said:
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.

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.
 
J

James Kanze

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.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,962
Messages
2,570,134
Members
46,692
Latest member
JenniferTi

Latest Threads

Top