Is there a way to detect ODR violations of the built-in function?

So, I have this code in two separate translation units:

// a.cpp #include <stdio.h> inline int func() { return 5; } int proxy(); int main() { printf("%d", func() + proxy()); } // b.cpp inline int func() { return 6; } int proxy() { return func(); } 

When compiling, usually the result is 10 . When compiled with -O3 (insert on), I get 11 .

I explicitly violated the ODR for func() .

It appeared when I started merging sources of different dlls with fewer DLLs.

I tried:

  • GCC 5.1 -Wodr (which requires -flto )
  • gold linker with -detect-odr-violations
  • ASAN_OPTIONS=detect_odr_violation=1 before running the tool binary with the sanitizer.

Asanas can allegedly catch other ODR violations (global varnas with different types or something like that)

This is a really nasty problem in C ++, and I am amazed there is no reliable toolkit to detect it.

Perhaps I misused one of the tools I tried? Or is there another tool for this?

EDIT

The problem goes unnoticed even when I make 2 func() implementations very different, so they do not compile with the same number of instructions.

It also affects class methods defined inside the class body - they are implicitly inlined.

 // a.cpp struct A { int data; A() : data(5){} }; // b.cpp struct A { int data; A() : data(6){} }; 

An outdated code with a lot of copies / pastes + minor changes after that is a joy.

+8
c ++ linker g ++ one-definition-rule linker-errors
source share
2 answers

The easiest way to detect such problems is to copy all the functions into a single compilation unit (if necessary, create it once). Any C ++ compiler will be able to detect and report duplicate definitions when compiling this file.

+3
source share

Tools are imperfect.

I think that Gold check will only mark when characters have different types or different sizes, which is wrong here (both functions will be compiled with the same number of instructions, just using a different instant value).

I'm not sure why -Wodr doesn't work here, but I think it only works for types, not functions, i.e. will detect two conflicting type definitions of class T , but not your func() .

I don't know anything about ASAN ODR validation.

+5
source share

All Articles