我有一个val.h
源代码文件,带有带有内部链接和内联函数的全局变量,该变量返回其地址:
// val.h
#pragma once
static int val;
inline int* get_val()
{
return &val;
}
然后,此标头包含在两个不同的翻译单元中。如果我在这两个单元中都调用&val
,则会得到两个不同的地址,这是可以的,因为val
具有内部链接,并且每个翻译单元都有自己的val
。但是,如果我在这两个单元中都调用get_val()
,则会得到两个相等的地址。
这种行为是否得到标准的保证,我们将始终从任何翻译单元获得get_val()
调用返回的相同值吗?
如果编译器决定进行真正的内联,即仅将每个翻译单元中的get_val()
调用替换为&val
语句,该怎么办?在这种情况下,每个翻译单位的地址会有所不同吗?
答案 0 :(得分:2)
您的函数违反了One Definition Rule,因为表达式val
引用了不同翻译单元中的不同实体。
它的行为是不确定的。
答案 1 :(得分:1)
有了它,将头文件包含在两个不同的翻译单元中时,您将得到不确定的行为。这是因为表达式return &val
将引用两个不同的对象;因此,getVal
的主体在两个翻译单元中都不同,但是getVal
具有外部链接。因此,您违反了一个定义规则。
要克服这个问题,您还必须为getVal
定义内部链接,即编写static int* get_val() { ...
。仅关键字inline
不会定义外部或内部链接。