1
  1. Consider a C++ header file compiled both in my_lib.a and in my_prog that links with my_lib.a. The library was compiled without NDEBUG, while my_prog - with NDEBUG. Would it result in ODR violation?
  2. What if my_lib.so is a shared library? Of course, ODR is irrelevant here, because there are 2 separate executables, but could NDEBUG affect std (or other) classes in a way that would prevent passing their instances correctly via SO interface? E.g. if an std::vector instance was created in my_prog, can it be passed as an argument to the SO? May NDEBUG affect memory allocation etc?

Does the Standard specify this?

curiousguy
  • 8,038
  • 2
  • 40
  • 58
Igor R.
  • 14,716
  • 2
  • 49
  • 83
  • 1
    If header file depends of NDEBUG (as use of `assert`), you have ODR violation in case 1. – Jarod42 Aug 13 '19 at 06:31
  • "ODR is irrelevant here" How is the ODR irrelevant during linking? – curiousguy Aug 21 '19 at 01:27
  • @curiousguy ODR may or may not be relevant in shared libraries; the situation gets more nuanced. We have to refer to the exact shared lib technology. If we are talking about Windows DLL's, and none of the inline functions affected by `NDEBUG` are `dllexport`, we probably don't have a problem. – Kaz Aug 21 '19 at 01:46
  • 1
    @Kaz Whatever the "technology" used, the C++ compiler is still allowed to assume C++ semantics which means that called ABI functions that are multiply defined are doing same exact stuff as the definition locally available (even if by another algorithm entirely). – curiousguy Aug 21 '19 at 01:54
  • 1
    @curiousguy What I'm saying is that multiply defined symbols may be in separate shared-lib-defined namespaces that are beyond C++. In that case, C++ rules like O.D.R. do not apply. – Kaz Aug 21 '19 at 04:32

1 Answers1

1

20.5.2.2 Headers [using.headers]

  1. A translation unit may include library headers in any order (Clause 5). Each may be included more than once, with no effect different from being included exactly once, except that the effect of including either <cassert> or <assert.h> depends each time on the lexically current definition of NDEBUG.

It is guaranteed not to be an issue for standard headers, however the issue you have highlighted does apply to functions in source files you provide yourself.

6.2 One-definition rule [basic.def.odr]

  1. There can be more than one definition of a class [function/enum/variable/etc] provided the definitions satisfy the following requirements:

[...] each definition of D shall consist of the same sequence of tokens;

Note that tokenisation happens after preprocessing, so if the definition contains any assert, this must preprocess to the same token sequence, i.e. must have the same NEDBUG setting during compilation.

BoBTFish
  • 19,167
  • 3
  • 49
  • 76
  • 1
    So, one has to maintain 2 sets of libraries: with NDEBUG and without, right? E.g. it would be incorrect to link debug version of an application with the release variant of Boost - whether it's linked statically or dynamically? – Igor R. Aug 13 '19 at 08:43