标签: comdat-folding

不同的功能有不同的地址吗?

考虑这两个功能:

void foo() {}
void bar() {}
Run Code Online (Sandbox Code Playgroud)

是保证&foo != &bar吗?

同样的,

template<class T> void foo() { }
Run Code Online (Sandbox Code Playgroud)

是保证&foo<int> != &foo<double>吗?


我知道折叠函数定义有两个连接器.

MSVC积极地COMDAT折叠函数,因此具有相同实现的两个函数可以转换为一个函数.作为副作用,这两个函数共享相同的地址.我的印象是这是非法的,但我无法找到标准中的哪些内容是非法的.

Gold链接器还可以折叠功能,包括a safeall设置. safe意味着如果采用了一个功能地址,它就不会折叠,all即使采用了地址也会折叠.因此safe,如果函数具有不同的地址,则黄金的折叠表现为.

虽然折叠可能是意料之外的,并且存在依赖于具有不同地址的不同(相同实现)函数的代码(因此折叠可能是危险的),在当前的C++标准下它实际上是非法的吗?(此时为C++ 14)(自然如果safe折叠是合法的)

c++ function-pointers one-definition-rule language-lawyer comdat-folding

51
推荐指数
4
解决办法
2185
查看次数

有没有办法为函数指针比较生成警告?

我花了很长时间才发现我的代码中有一个错误被触发/OPT:ICF:

因为/ OPT:ICF可以将相同的地址分配给不同的函数或只读数据成员(使用/ Gy编译的const变量),它可以破坏依赖于函数或只读数据成员的唯一地址的程序.

(我一直在存储和比较函数指针的相等性,当链接器丢弃相同的函数时会断开这些指针.)

现在我需要找到我可能做过这样事情的每一个地方.

测试用例当然是微不足道的:

//MSVC: /Gy /link /OPT:ICF
int test1(void) { return 0; }
int test2(void) { return 0; }
int main(void) { return test1 == test2; }
Run Code Online (Sandbox Code Playgroud)

我试过-Wall,-Wextra,-Weverything,-pedantic,等,但他们没有产生警告.

是否有任何编译器选项或工具(无论是Visual C++,GCC,Clang还是其他部分)可以分析我的代码并告诉我在哪里比较函数指针,就像在上面的代码中一样?

c c++ function-pointers compiler-warnings comdat-folding

29
推荐指数
1
解决办法
800
查看次数

用于 COMDAT 折叠的 MSVC 编译器和链接器选项之间的关系

这个问题在 SO 上有一些答案,但我的略有不同。在标记为重复之前,请试一试。

MSVC 一直提供 /Gy编译器选项,以允许将相同的函数折叠到 COMDAT 部分中。同时,链接器还提供了 /OPT:ICF 选项。我的理解是这两个选项必须结合使用吗?也就是说,前者将函数封装到 COMDAT 中,后者消除了冗余的 COMDAT。那是对的吗?

如果是,那么我们要么同时使用要么都关闭?

compiler-construction linker visual-c++ comdat-folding

5
推荐指数
1
解决办法
581
查看次数