[bind10-dev] Compilation failure on master with g++

JINMEI Tatuya / 神明達哉 jinmei at isc.org
Sun Jun 26 03:04:47 UTC 2011


At Sat, 25 Jun 2011 14:09:37 +0200,
Michal 'vorner' Vaner <michal.vaner at nic.cz> wrote:

> Current master fails to compile for me (with g++ 4.5.2 on Gentoo):
> run_unittests-ip_check_unittest.o: In function `isc::acl::IPCheck<(anonymous namespace)::GeneralAddress>::getAddress() const':
> /home/vorner/work/bind10/src/lib/acl/tests/../../../../src/lib/acl/ip_check.h:258: undefined reference to `isc::acl::IPCheck<(anonymous namespace)::GeneralAddress>::IPV4_SIZE'
[...] 
> After looking at it, I found out that the compiler is correct according to this:
> http://publib.boulder.ibm.com/infocenter/comphelp/v8v101/index.jsp?topic=%2Fcom.ibm.xlcpp8a.doc%2Flanguage%2Fref%2Fcplr038.htm
> (down at the page, last 3 paragraphs).

I suspect this document is outdated (if not just wrong).
I don't have a formal C++ language reference in my hand right now, but
according to the Stroustrup's "The C++ Programming Language":

  If (and only if) you use an initialized member in a way that
  requires it to be stored as an object in memory, the member must be
  (uniquely) define somewhere.

So, for example, if the example used in the above URL were this one:

struct X {
  static const int a = 76;
};

const int X::a; // this cannot be omitted
const int *p = &X::a;

it would be correct; we cannot omit the explicit definition (and my
clang++ and g++ compilers correctly complain about that in this
revised case, while they happily compile the original example.

Perhaps the fact that templated cases (like ours) have different
rules, but I couldn't find it in literature.  My guess is it's a
compiler bug specific to the templated case - maybe it considers
the type also templated (and thus possibly a non integral type).

BTW, we already encountered this type of problems and worked them
around by providing explicit definitions.  See, e.g.,
src/lib/bench/tests/benchmark_unittest.cc.

> I tried to provide the definitions, but it fails with static const template
> members for some reason.

So, don't these (in ip_check.h) work for you?

template <typename Context>
const size_t IPCheck<Context>::IPV6_SIZE;

template <typename Context>
const size_t IPCheck<Context>::IPV4_SIZE;

If not,

> Therefore I propose this patch to fix the compilation and
> wastefulness. It has the disadvantage that the IPV?_SIZE symbols are
> visible, but I didn't come with a better solution that would work
> for my compiler.

I'm okay with this workaround, but would at least move them inside the
"internal" namespace to mitigate the disadvantage you said.  I'd also
leave a comment about why we doing this.

BTW,

> I also noticed the constants are not template dependant at all, so having a
> different instance for each template parameter is wasteful.

I suspect it matters much in practice.  Since they are very simple
constants, compilers will be reasonable enough to avoid generating
redundant definitions.

---
JINMEI, Tatuya
Internet Systems Consortium, Inc.



More information about the bind10-dev mailing list