考虑这两个功能:
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 safe和all设置. safe意味着如果采用了一个功能地址,它就不会折叠,all即使采用了地址也会折叠.因此safe,如果函数具有不同的地址,则黄金的折叠表现为.
虽然折叠可能是意料之外的,并且存在依赖于具有不同地址的不同(相同实现)函数的代码(因此折叠可能是危险的),在当前的C++标准下它实际上是非法的吗?(此时为C++ 14)(自然如果safe折叠是合法的)
c++ function-pointers one-definition-rule language-lawyer comdat-folding
我有一个非常奇怪的问题,我已经简化为以下测试用例:
#include <iostream>
#include <map>
#include <string>
struct Test
{
std::map<std::string, void (Test::*)()> m;
Test()
{
this->m["test1"] = &Test::test1;
this->m["test2"] = &Test::test2;
}
void test1() { }
void test2() { }
void dispatch(std::string s)
{
if (this->m.at(s) == &Test::test1)
{ std::cout << "test1 will be called..." << std::endl; }
else if (this->m.at(s) == &Test::test2)
{ std::cout << "test2 will be called..." << std::endl; }
(this->*this->m.at(s))();
}
};
int main()
{
Test t;
t.dispatch("test1");
t.dispatch("test2");
}
Run Code Online (Sandbox Code Playgroud)
它输出
test1将被调用...
test1将被调用...
当启用优化时,这真的很奇怪.这是怎么回事?
好奇的是,GCC或Clang工具集目前是否实现了相同的MSVC 相同的COMDAT折叠(ICF)?如果没有,有什么计划吗?除了旧的GCC邮件列表消息之外,我似乎无法找到关于该主题的任何最新权威链接.
如果不是,这是否意味着不同类型的模板实例化在结果二进制文件中始终是不同的函数(在它们没有完全内联的情况下),即使它们是二进制兼容的,或者是否存在其他机制来处理它在其他一些水平?
此外,有没有人发现ICF在最大限度地减少实际可执行文件的大小方面有很大的不同?我没有任何大型MSVC项目可以方便地进行测试.(我猜它只是真的有帮助,如果你碰巧在许多不同的vtable-layout兼容类型上实例化模板.)
最后,是否符合C++ 11标准的两个函数指针指向不同的函数,以便在运行时进行相等比较?这个链接似乎意味着它不是,但它适用于C99.编辑:发现此主题的上一个问题