- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
当我尝试构建这段代码时
inline void f() {}
int main()
{
f();
}
使用命令行
gcc -std=c99 -o a a.c
我收到链接器错误(对 f
的 undefined reference )。如果我使用 static inline
或 extern inline
而不仅仅是 inline
,或者如果我使用 -O
进行编译,错误就会消失>(所以函数实际上是内联的)。
这种行为似乎在 C99 标准的第 6.7.4 (6) 段中定义:
If all of the file scope declarations for a function in a translation unit include the
inline
function specifier withoutextern
, then the definition in that translation unit is an inline definition. An inline definition does not provide an external definition for the function, and does not forbid an external definition in another translation unit. An inline definition provides an alternative to an external definition, which a translator may use to implement any call to the function in the same translation unit. It is unspecified whether a call to the function uses the inline definition or the external definition.
如果我对这一切的理解是正确的,那么只有当还有一个具有相同名称的外部函数时,如上例中定义了 inline
函数的编译单元才会一致地编译,而且我不知道是否我自己的函数或外部函数被调用。
这种行为是不是很愚蠢?在 C99 中定义没有 static
或 extern
的函数 inline
有用吗?我错过了什么吗?
当然,我遗漏了一些东西,而且这种行为并不愚蠢。 :)
作为Nemo explains , 思路是把函数的定义
inline void f() {}
在头文件中,只有一个声明
extern inline void f();
在对应的.c文件中。只有 extern
声明会触发生成外部可见的二进制代码。在 .c 文件中确实没有使用 inline
-- 它只在标题中有用。
作为rationale of the C99 committee quoted in Jonathan's answer explicates,inline
是关于编译器优化的,它要求函数的定义在调用位置可见。这只能通过将定义放在 header 中来实现,当然, header 中的定义不能每次被编译器看到时都发出代码。但是由于编译器并没有被迫实际内联一个函数,所以外部定义必须存在于某处。
最佳答案
其实这个优秀的答案也回答了你的问题,我认为:
想法是可以在头文件中使用“inline”,然后在.c 文件中使用“extern inline”。 “外部内联”就是您指示编译器哪个目标文件应包含(外部可见的)生成代码的方式。
[更新,详细说明]
我认为 .c 文件中的“内联”(没有“static”或“extern”)没有任何用处。但在头文件中它是有意义的,并且它需要在某些 .c 文件中相应的“extern inline”声明才能实际生成独立代码。
关于c - 没有 "inline"或 "static"的 "extern"在 C99 中有用吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6312597/
我是 F# 的菜鸟,目前正在阅读 F# 3.0 中的专家。 它是我学习的第一种编译语言(我只知道用 R 编程) 在第 6 章第 117 页,我们没有太多仪式性地介绍 静态让和静态成员。我真的不明白它是
我很迷茫。我已经花几个小时广泛地复习了我的两个类(class)。没有什么是静态的,没有什么是静态引用的,但我无法摆脱这个错误。 A 类文件 (ClassA.php) privateVariable =
关于类公共(public)类声明,请看这两段代码: public class Helper { public static void CallMeganFox(string phoneNumb
我如何使用“super”关键字从父类(super class)(类“aa”)引用“a1” class aa { protected static int a1 = 2; } public class
class Perkusja { boolean talerze = true; boolean beben = true; void zagrajNaBebnie() { Sys
我试图在编译 C++ 程序时静态链接库。 g++ (GCC) 4.8.5 20150623(红帽 4.8.5-4) $ g++ -std=c++11 -I/home/jerry/Desktop/tin
$ javac TestFilter.java TestFilter.java:19: non-static variable this cannot be referenced from a sta
这个问题在这里已经有了答案: How do I create a global, mutable singleton? (7 个答案) How can you make a safe static
“覆盖”静态数组时我遇到了一个棘手的问题。我有静态数组(为简单起见),它们在不同的派生类中具有固定长度,但在编译时仍然知道所有大小。我在基类中也有一个虚函数,但我不知道如何解决在派生类中覆盖这些数组和
我刚刚在遗留代码中发现了这一点。我知道使用宏,每当使用名称时,它都会被宏的内容替换。它们最常用于为数字常量提供符号名称。我所知道的是预处理没有类型安全、范围的概念。 这样做的真正好处是什么? #def
将 Singleton 实例声明为 static 还是声明为 static final 更好? 请看下面的例子: 静态版本 public class Singleton { private s
问题: 我观察到的行为是 TypeScript 的预期行为吗? 我观察到的行为是 ECMAScript 6 的预期行为吗? 是否有一种简单的方法可以返回继承层次结构以处理每个级别的“myStatic”
在php中,访问类的方法/变量有两种方法: 1. 创建对象$object = new Class(),然后使用”->”调用:$object->attribute/functi
我尝试向 ExpandoObject 添加一个动态方法,该方法会返回属性(动态添加)给它,但它总是给我错误。 我在这里做错了吗? using System; using System.Collecti
我试图获得一个静态链接到我的程序的音频库。我用 this灵活的包。为了让它运行,我必须按照描述构建 soloud 库 here .下载后不久,我在“build”文件夹中运行了“genie --with
这是我的webpack.prod.config.js代码 const path = require('path'); const { CleanWebpackPlugin } = require('c
我想知道什么时候应该对变量和(或)方法使用静态、最终、静态最终参数。据我了解: final:类似于c++中的const参数。它基本上意味着值(或在方法中 - 返回值)不会改变。 静态:这意味着值(或方
我一直在阅读有关使用静态对象作为锁的内容,最常见的示例如下: public class MyClass1 { private static final Object lock = new Obje
在 Visual Basic 2008 中,我知道有两种不同的方法可以完成同一件事: 成员(member)级别的 Dim: Dim counter1 as integer = 0 Dim counte
static public final int i = 0; public static final int i = 0; 两者都工作正常。 为什么同样的事情可以用两种不同的风格来完成? 最佳答案 因
我是一名优秀的程序员,十分优秀!