0
votes

I'm looking for some secure coding guideline and came across the SEI CERT C++ Coding Standard.

Most things are clear so far, but I don't understand the last Noncompliant Code Example from DCL60-CPP: Obey the one-definition rule.

In this noncompliant code example, the constant object n has internal linkage but is odr-used within f(), which has external linkage. Because f() is declared as an inline function, the definition of f() must be identical in all translation units. However, each translation unit has a unique instance of n, resulting in a violation of the ODR.

const int n = 42;

int g(const int &lhs, const int &rhs);

inline int f(int k) {
    return g(k, n);
}

I tried to put the shown code in a header file and included it in two separate cpp files. I then compiled it with clang++ and g++. Both without warnings. It executed normally.

Edit: So what I don't understand is how or under what circumstances the shown Example violates the ODR.

1
ODR violations are not required to be diagnosed. Not getting an error or warning does not mean it is okay. - NathanOliver
What exactly is your question? - Max Langhof
"Both without warnings. It executed normal." - Compilers are not required to diagnose ODR violations. They may do so (build with Link Time Optimization increases those chances), but it's purely a "quality of impletation" issue whether they do or not. The compiler is completely within its right to assume no ODR violation. In the end, it's entirely your responsibility that there are no ODR violations in your code. If you do violate ODR and the compiler ends up generating broken stuff, it's on you and you get to keep the broken pieces of your program when it blows up in your face. - Jesper Juhl
constexpr might solve issues, or some tricks such as return g(k, +n);. - Jarod42

1 Answers

0
votes

You did violate the ODR. Violating the ODR is "undefined behaviour".

One of the more common forms of undefined behaviour is "doing exactly what the programmer expected". In my experience though, an even more common form is "doing exactly what the programmer expected nearly all the time, but crashing randomly occassionally".

This particular UB will probably always work - until you switch on improved link-time optimizations, when it may all come crashing down in a heap around your head.