有没有办法检测内联函数ODR违规? [英] Is there a way to detect inline function ODR violations?

查看:857
本文介绍了有没有办法检测内联函数ODR违规?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以我有两个单独的翻译单元中的代码:

  // 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(); }

编译通常结果是 10 。当使用-O3编译时(内联),我得到了 11



code> func()。



当我开始将不同dll的源代码合并为更少的dll时,

我试过:


  • GCC 5.1 -Wodr (它需要 -flto
  • 黄金链接器与 -detect-odr-violations

  • 设置 ASAN_OPTIONS = detect_odr_violation = 1 ,然后使用地址清理程序运行带检测的二进制文件。



Asan可以抓住其他ODR违规行为(具有不同类型的全局变量或类似的东西......)

这是一个非常讨厌的C ++问题,我很惊讶没有可靠的工具来检测它。



也许我滥用了我尝试过的工具之一?或者是有不同的工具吗?



编辑

即使当我使得 func()> 2的两个实现完全不同时,它们仍然未被注意到,因此它们不会被编译为相同数量的指令。



这也会影响类体内定义的类方法 - 它们是隐式内联的。

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

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

在此之后有大量复制/粘贴+小修改的旧代码是一种快乐。

解决方案

检测此类问题的最简单方法是将所有函数复制到单个编译单元中(如果需要,则临时创建一个)。任何C ++编译器都可以在编译该文件时检测并报告重复定义。


So I have this code in 2 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 compiled normally the result is 10. When compiled with -O3 (inlining on) I get 11.

I have clearly done an ODR violation for func().

It showed up when I started merging sources of different dll's into fewer dll's.

I have tried:

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

Asan can supposedly catch other ODR violations (global vars with different types or something like that...)

This is a really nasty C++ issue and I am amazed there isn't reliable tooling for detecting it.

Pherhaps I have misused one of the tools I tried? Or is there a different tool for this?

EDIT:

The problem remains unnoticed even when I make the 2 implementations of func() drastically different so they don't get compiled to the same amount of instructions.

This also affects class methods defined inside the class body - they are implicitly inline.

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

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

Legacy code with lots of copy/paste + minor modifications after that is a joy.

解决方案

The simplest way to detect such concerns is to copy all the functions into a single compilation unit (create one temporarily if needed). Any C++ compiler will then be able to detect and report duplicate definitions when compiling that file.

这篇关于有没有办法检测内联函数ODR违规?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆