- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我对 C99 中的 inline
感到困惑。
这是我想要的:
.c
文件)。static inline
)。C++ inline
正是这样做的。
但是(如果我错了请纠正我)在 C99 中没有办法获得这种行为。
我本可以使用 static inline
,但它会导致重复(同一函数在不同翻译单元中的地址不一样)。我不想要这种重复。
所以,这是我的问题:
inline
背后的想法是什么?引用资料:
inline
的链接,但我不明白为什么。这种“只在一个编译单元中”的限制真的那么好吗?inline
的基本原理。看过了,没看懂。inline
函数的策略。inline
行为(是的,我们可以)head.h
#ifndef __HEAD_H__
#define __HEAD_H__
inline int my_max(int x, int y) {
return (x>y) ? (x) : (y);
}
void call_and_print_addr();
#endif
src.c
#include "head.h"
#include <stdio.h>
// This is necessary! And it should occurs and only occurs in one [.c] file
extern inline int my_max(int x, int y);
void call_and_print_addr() {
printf("%d %u\n", my_max(10, 100), (unsigned int)my_max);
}
main.c
#include <stdio.h>
#include "head.h"
int main() {
printf("%d %u\n", my_max(10, 100), (unsigned int)my_max);
call_and_print_addr();
return 0;
}
编译它:gcc -O3 main.c src.c -std=c99
检查程序集: gcc -O3 -S main.c src.c -std=c99
,您会发现 my_max
内联在 call_and_print_addr()
和 main()
中。
实际上,这与引用 1 和引用 3 给出的指令完全相同。我怎么了?
我用了一个太旧版本的GCC (3.4.5) 来实验,它给了我“multiple definition of my_max
”的错误信息,这就是我如此困惑的真正原因。耻辱。
inline
实际上你可以通过g++
编译上面的例子:g++ main.c src.c
extern inline int my_max(int x, int y);
在 C++ 中是多余的,但在 C99 中是必需的。
那么它在C99中有什么作用呢?
同样,使用 gcc -O3 -S main.c src.c -std=c99
,你会在 src.s
中找到类似这样的东西:
_my_max:
movl 4(%esp), %eax
movl 8(%esp), %edx
cmpl %eax, %edx
cmovge %edx, %eax
ret
.section .rdata,"dr"
如果您剪切 extern inline int my_max(int x, int y);
并将其粘贴到 main.c
中,您将在 main.s
中找到这些汇编代码。
因此,通过 extern inline
,您告诉编译器将在哪里定义和编译真正的函数 my_max()
,您可以通过其地址调用它。
现在回过头来看C++,我们是不能指定的。我们永远不会知道 my_max()
会在哪里,这是@Potatoswatter 的“模糊链接”。
正如@Adriano 所说,大多数时候,我们并不关心这个细节,但 C99 确实消除了歧义。
最佳答案
要获得类似 C++ 的行为,您需要为每个具有潜在内联调用的 TU 提供一个 inline
定义,并为一个 TU 提供一个外部可见的定义。这正是 C 标准相关部分(函数说明符)中示例 1 所说明的内容。 (在那个例子中,外部可见性通过在之后声明函数 extern
追溯应用于 inline
定义:这个声明可以在 .c
在 .h
文件中定义之后的文件,这颠覆了通常的用法。)
如果内联可以在任何地方完成,你就不需要 extern
函数了。但是,在递归和引用函数地址等上下文中使用非内联调用。从某种意义上说,您可能会通过省略 extern
部分来获得“始终内联”的语义,但是对于任何简单的函数调用,这可能会任意失败,因为标准并不要求内联调用只是因为有是别无选择。 (这是 linked question 的主题。)
C++ 使用“模糊链接”的实现概念来处理这个问题;这在标准中没有指定,但在编译器内部是非常真实且棘手的。 C 编译器应该比 C++ 更容易编写;我相信这可以解释语言之间的差异。
关于c - C99 inline 背后的想法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23272985/
所以这个有点难以解释,但我会尝试一下: 我有一个带有 .boxes 类的 div。它是一些循环元素的包装。循环元素具有类.box。在这个元素中,还有两个元素。一种是 .box-header 类的 he
我有一个网站,我试图在调整浏览器窗口大小时使其表现得体。例如,我希望在有人缩小浏览器窗口时调整横幅图像的大小。网址是http://www.pfp-consortium.org 顶部的横幅在 CSS 中
我想知道情况,是将所有可能的元素都放在表单中更好,还是在用户需要时立即将元素添加到表单中更好。 我将尝试对其进行更多解释 - 我的表单具有 4 个输入和一个文本区域。然后我提供了可选值(大约 15 -
很难说出这里要问什么。这个问题模棱两可、含糊不清、不完整、过于宽泛或夸夸其谈,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开,visit the help center . 关闭 1
所以我一直在研究我正在构建的一个论坛,并且一直专注于它的一个方面,即如何在不在数据库中存储大量数据的情况下跟踪未读的帖子和通知。在查看了一些解决方案之后,我相信我想出了一个可能适合我需要的解决方案,但
编写一个高质量的软件应该是第一步。现在这是一个移动的目标。(我们有一些类似于 https://stackoverflow.com/questions/3716203/automatic-code-qu
我有一组存储在数组中的二维点。 我需要尽可能多地压缩它。最好是快速,但不要破坏交易,压缩率是目标。规则是: 一个点=一个32位的结构,存储为(x,y),每个坐标2个字节 坐标 = 8 位整数部分和 8
我的一个应用程序从服务器下载数据库。当我将应用程序安装到我的手机上时,它会正确下载文件并加载信息,没有抛出任何异常或任何东西。 但是,当我将 apk 上传到 Android Market Place
我们最近接到一位客户的电话,提示他们网站的页面底部有一些“看起来很奇怪的代码”。我们查看了源代码,发现 templates/master 中附加了大约 800 字节的恶意 javascript 代码。
以编程方式创建系统还原点是“禁忌”吗?我会在执行软件更新之前执行此操作。如果有更好的方法可以仅使用我的软件文件和数据创建还原点,请告诉我。 我想要一种方法,如果在更新期间一切都发生了故障(关闭/终止更
我有一个有很多相关模型的类问题。在我的应用程序的一个页面上,我列出了所有当前问题的摘要,以及来自相关记录的各种信息。最终,这是一个值的散列,然后我将其打印到一个 csv 样式的行中(从这里我将其称为“
我目前正在尝试从 NSClassFromString(NSString *) 方法创建对象。 我希望能够实现的是以下... NSClassFromString(stringType) *pageCon
使用 Intellij 想法,我如何找出使变量可见的原因? 困难时的示例: 假设你看 class A ,你会看到一个变量 something .如果你跳转到源代码,你会看到它是在 trait X 中定
在IntelliJ IDEA的代码样式设置中,没有.gradle文件的任何子类别(例如build.gradle),在“其他文件类型”下,没有任何选项可以修改花括号位置。我没有找到为.gradle文件设
我正在尝试按照here指令运行docker-compose,但它似乎陷入了循环。在安装Docker之前,我能够调出示例站点并进行一些外观上的更改,但是尝试使用docker-compose生成缩略图23
我正在使用 IntelliJ IDEA 12.1.4 来调试 Grails 应用程序。我开始调试 session 大约需要 2 分钟。我想尽可能避免重新启动。 我正在尝试调试一个 Controller
随着 .NET 4.0 的出现,MS AJAX 是否仍占有一席之地,或者您认为 JQuery 是否会扩展以包含 AJAX 的全部功能,并使我们所知的 MS AJAX 变得多余? 最佳答案 请记住,AS
需要帮助运行此示例 Google+ API Quickstart w/C# 应用程序,请使用 VS2015 并按照此处的说明操作:https://developers.google.com/+/web
很难说出这里要问什么。这个问题模棱两可、含糊不清、不完整、过于宽泛或夸夸其谈,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开,visit the help center . 关闭 1
我有一个相当“疯狂”的想法,即在我的应用程序中拥有一个“存储过程”设施。基本上,我的应用程序以数据为中心,它可以通过某种形式的 Restful 界面访问数据存储。 我希望拥有以多种方式操作数据(这是一
我是一名优秀的程序员,十分优秀!