我对inline
C99感到困惑。
这是我想要的:
- 我希望我的函数在任何地方都被内联,而不仅仅是一个翻译单元(或一个编译单元,一个
.c
文件)。 - 我希望函数的地址一致。如果我将函数的地址保存在函数指针中,我希望函数可以从指针调用,并且我不希望在不同的翻译单元中重复相同的函数(基本上,我的意思是 no
static inline
)。
C++inline
正是这样做的。
但是(如果我错了,请纠正我)在 C99 中没有办法得到这种行为。
我可以使用static inline
,但它会导致重复(不同翻译单元中相同函数的地址不一样)。我不想要这种重复。
所以,这是我的问题:
inline
C99背后的想法是什么?- 与 C++ 的方法相比,这种设计有什么好处?
参考:
- 这是一个高度评价 C99 的链接
inline
,但我不明白为什么。这种“仅在一个编译单元中”的限制真的那么好吗?
http://gustedt.wordpress.com/2010/11/29/myth-and-reality-about-inline-in-c99/ - 这是 C99 的基本原理
inline
。我读过,但我不明白。
没有“静态”或“外部”的“内联”在 C99 中有用吗? - 一篇不错的帖子,提供了使用
inline
函数的策略。
http://www.greenend.org.uk/rjk/tech/inline.html
答案摘要
如何inline
在 C99 中获得 C++ 行为(是的,我们可以)
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) 进行实验,它给了我“多重定义my_max
”的错误信息,这才是我如此困惑的真正原因。耻辱。
C99 和 C++ 的区别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 确实消除了歧义。