我理解"内联"本身就是对编译器的建议,并且在它的结构中它可能会或可能不会内联函数,它也会产生可链接的目标代码.
我认为"静态内联"执行相同的操作(可能内联也可能不内联),但在内联时不会产生可链接的目标代码(因为没有其他模块可以链接到它).
"extern inline"在哪里适合图片?
假设我想用内联函数替换预处理器宏,并要求此函数被内联(例如,因为它使用__FILE__和__LINE__宏,这些宏应该为调用者而不是这个调用函数解析).也就是说,如果函数没有内联,我想看到编译器或链接器错误."extern inline"这样做吗?(我假设,如果没有,除了坚持使用宏之外,没有办法实现这种行为.)
C++和C之间是否存在差异?
不同编译器供应商和版本之间是否存在差异?
在K&R C或C89中,内联不是该语言的一部分.许多编译器将其实现为扩展,但没有关于它如何工作的定义语义.GCC是第一个实施内联外,并介绍了inline
,static inline
和extern inline
构造; 大多数前C99编译器一般都遵循其领先优势.
inline
:函数可能是内联的(虽然它只是一个提示).始终发出外部版本并且外部可见.因此,您只能在一个编译单元中定义这样的内联,并且每个其他人都需要将其视为一个外联函数(或者您将在链接时获得重复的符号).
extern inline
不会生成一个外联版本,但可能会调用一个版本(因此您必须在其他编译单元中定义.但是,单定义规则适用;外联版本必须具有与在这里提供内联,以防编译器调用它.
static inline
虽然它可能生成静态文件,但不会生成外部可见的外部版本.单定义规则不适用,因为从不发出外部符号,也不调用一个.
C99(或GNU99):
inline
:像GNU89"extern inline"; 没有发出外部可见的函数,但可能会调用一个函数,因此必须存在
extern inline
:像GNU89"inline":发出外部可见代码,因此最多只有一个翻译单元可以使用它.
static inline
:像GNU89"静态内联".这是gnu89和c99之间唯一的便携式
C++:
在任何地方内联的函数必须在任何地方内联,具有相同的定义.编译器/链接器将对符号的多个实例进行排序.没有定义static inline
或者extern inline
,虽然许多编译器都有它们(通常遵循gnu89模型).
我相信你基于这个陈述误解__FILE__和__LINE__:
因为它使用了__FILE__和__LINE__宏,这些宏应该为调用者而不是这个被调用的函数解析
编译有几个阶段,预处理是第一阶段.__FILE__和__LINE__在该阶段被替换.因此,当编译器可以考虑内联函数时,它们已经被替换.
听起来你正在尝试写这样的东西:
inline void printLocation() { cout <<"You're at " __FILE__ ", line number" __LINE__; } { ... printLocation(); ... printLocation(); ... printLocation();
并希望你每次都会得到不同的价值.正如Don所说,你不会,因为__FILE__和__LINE__是由预处理器实现的,但内联是由编译器实现的.所以无论你从哪里调用printLocation,你都会得到相同的结果.
使这个工作的唯一方法是使printLocation成为一个宏.(是的我知道...)
#define PRINT_LOCATION {cout <<"You're at " __FILE__ ", line number" __LINE__} ... PRINT_LOCATION; ... PRINT_LOCATION; ...