c - 外部链接内联函数真的是内联的吗?

标签 c language-lawyer inline extern

来自 C18 标准:

If all of the file scope declarations for a function in a translation unit include the inline function specifier without extern, then the definition in that translation unit is an inline definition.


然后我们读到:

The declaration of an inline function with external linkage can result in either an external definition, or a definition available for use only within the translation unit. A file scope declaration with extern creates an external definition.


我已经编写了一些代码来检查该函数是否实际上是内联的。我已经使用此限制来找出:

An inline definition of a function with external linkage shall not contain a definition of a modifiable object with static or thread storage duration, and shall not contain a reference to an identifier with internal linkage.


这是代码:
static int n = 5;

void inline foo() { n = 66; }
void inline foo();    // remove 'inline' in second version

int main() {
    return 0;
}
编译时,我收到一条警告说内联函数正在使用静态对象,这意味着 foo()实际上,它是一个内联函数,因此它提供了一个内联(而非外部)定义。但是,当我删除 inline 时来自指示行的说明符,我不再收到警告。根据标准,它不是内联定义,所以我猜它提供了外部定义。
标准没有说,或者至少我看不到,是提供外部定义的内联函数是否不再是内联函数。根据我的测试,它确实不再是内联函数。
如果我的结论是正确的(我不知道),那么就会出现另一个问题:为什么 extern 内联函数是无用的东西?

最佳答案

在问题中,您尝试在编译器中尝试并推断语言规则。这通常是一个坏主意,因为 (a) 在许多情况下,违反规则的影响很难观察到,并且 (b) 编译器可能会被窃听。相反,标准是语言规则的权威来源,因此应通过引用标准来回答问题。

继续:您的代码包含违反 C11 6.7.4/3 的约束,您在问题中引用了该约束。违反约束的结果是编译器必须发出诊断,它确实做到了。
然后你问一些修改,我假设你的意思是以下代码:

static int n = 5;
void inline foo() { n = 66; }
void foo();
int main() { return 0; }
正如您引用的第一句话(来自 6.7.4/7)所涵盖的那样,foo() 的定义不是内联定义,因为并不是所有 TU 中的文件范围声明都包含 inline不带 extern 的说明符. (这句话的意思是 deny the antecedent )。
由于不是内联定义,所以n = 66没有问题并且代码是正确的。

What the standard is not saying, or at least I cannot see it, is whether an inline function that provides an external definition stops being an inline function, or not


内联函数定义绝不是外部定义。这在 6.7.4/7“内联定义不提供函数的外部定义”中有明确说明。
也许您的困惑源于将概念“内联函数定义”和“函数定义与 inline 说明符”混为一谈。

another question arises: why an extern inline function is a useless thing?


如果您的意思是关键字 extern inline这是这个问题没有涉及的另一个话题,see here .带有外部链接的内联函数当然不是无用的。

关于c - 外部链接内联函数真的是内联的吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63629807/

相关文章:

c++ - 涉及函数类型的表达式是左值还是右值?

c++ - "else if"是单个关键字吗?

inline - 图片在加载时重叠

c - Linux模块编译: struct evdev member not found

c - TreeView 更改项目图像的颜色

C 结构数据在迭代循环外无法保持一致

c++ - 在哪里定义了名称查找规则来查找最直接的名称声明?

html - 为什么我的 div 不保持一致?

objective-c - Objective-C 中的静态、外部和内联

c - 用 LD_PRELOAD 覆盖 execve() 有时只有效