考虑这两个功能:
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
在C++中,如果在header.hpp中定义此函数
void incAndShow()
{
static int myStaticVar = 0;
std::cout << ++myStaticVar << " " << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
并且在至少两个.cpp文件中包含header.hpp.然后你会有multiple definition of incAndShow().这是预期的.但是,如果您向该函数添加模板
template <class T>
void incAndShow()
{
static int myStaticVar = 0;
std::cout << ++myStaticVar << " " << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
那你就不会有任何multiple definition of错误.同样,两个不同的.cpp调用具有相同模板(例如incAndShow<int>())的函数将共享myStaticVar.这是正常的吗?我问这个问题,因为我确实依赖于这个"功能"(共享静态变量),我想确保不仅是我的实现正在这样做.
为什么这样做?
我看到类似的SO问题说它确实如此,但有人可以更详细地解释它吗?特别是,这种行为是否受到标准的保护?
IH
#ifndef I_H_
#define I_H_
typedef void (*FuncPtr)();
template<typename T>
void FuncTemplate() {}
class C {};
#endif
Run Code Online (Sandbox Code Playgroud)
a.cc
#include "i.h"
FuncPtr a() {
return &FuncTemplate<C>;
}
Run Code Online (Sandbox Code Playgroud)
b.cc
#include "i.h"
FuncPtr b() {
return &FuncTemplate<C>;
}
Run Code Online (Sandbox Code Playgroud)
m.cc
#include <iostream>
#include "i.h"
FuncPtr a();
FuncPtr b();
int main() {
std::cout << (a() == b() ? "equal" : "not equal") << std::endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
然后
$ g++ -c -o a.o a.cc
$ g++ -c -o b.o b.cc
$ g++ -c …Run Code Online (Sandbox Code Playgroud)