考虑这两个功能:
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
我刚刚在这里阅读了一个有趣的问题,让我想到了另外两件事:
void *
或是否持有更丰富的信息(如返回类型,论点和论据类型的号码?)我有一个非常奇怪的问题,我已经简化为以下测试用例:
#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将被调用...
当启用优化时,这真的很奇怪.这是怎么回事?
我希望以下程序一直返回0.但是,对于Visual Studio 2013(Update 4),程序在发布版本中退出1.我不确定这是一个错误,还是编译器的优化器是正确的,并且依赖于某些边缘行为.如果关闭CONST宏,则release exe返回0.如果优化器确实正确,我是否可以获得允许它发出代码的原因?
#if 1
# define CONST const
#else
# define CONST
#endif
class TypeId {
public:
bool operator== (TypeId const & other) const
{
return id == other.id;
}
private:
TypeId (void const * id)
: id(id)
{}
public:
template <typename T>
static TypeId Get ()
{
static char CONST uniqueMemLoc = 0;
return TypeId(&uniqueMemLoc);
}
private:
void const * id;
};
int main(int, char **)
{
typedef int A;
typedef unsigned int B;
if (TypeId::Get<A>() …
Run Code Online (Sandbox Code Playgroud)