考虑到以下设置,我遇到了一个非常奇怪的现象,我无法真正解释。使用 Visual Studio 2005,以下代码会导致崩溃。我真的很想知道原因。
Playground .cpp
static int local=-1;
#include "common.h"
int main(int arg)
{
setit();
docastorUpdate();
return 0;
}
common.h
#include <stdio.h>
#include <iostream>
void docastorUpdate();
static int *gemini;
inline void setit()
{
gemini = &local;
}
castor.cpp
static int local = 2;
#include "common.h"
void docastorUpdate() {
setit();
// crashing here, dereferencing a null pointer
std::cout << "castor:" << *gemini << std::endl;
}
问题是,当崩溃消失
- 我将内联函数 setit() 移动到未命名的命名空间
- 我把它设为静态
简而言之,我需要帮助才能理解原因。任何建议表示赞赏! (我知道,这个解决方案不是最好的部分之一,只是好奇。)
最佳答案
这会中断,因为您违反了单一定义规则。一个定义规则表示在一个程序中,在所有翻译单元中,任何给定函数只有一个定义。 inline
是这条规则的一个异常(exception),它或多或少意味着“亲爱的编译器,这个函数会有多个定义,但它们都是相同的,我保证”。
static
,当在这里用于 local
时,意思是“亲爱的编译器,这是一个只有这个翻译单元才能看到的内部细节;请不要将它与来自其他翻译单元的名为 local
的变量”
所以你向编译器保证 setit
的所有定义都将相同,并要求编译器为每个翻译单元提供它自己的 local
变量。
但是,由于 setit
函数使用范围内名为 local
的任何变量,最终结果是 setit
的两个不同定义,每个一个使用不同的变量。 你刚刚违背了 promise 。编译器信任你,结果是一个完全困惑的程序。它认为它可以根据你的 promise 用代码做某些事情,但由于你在背后破坏了它们,它试图用代码做的那些事情根本不起作用。
关于c++ - 关于 C++ 中全局内联函数的示例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20000856/