外部内联
我明白,“内联”本身就是对编译器的一种build议,在其内容中可能会或可能不会内联函数,也会产生可链接的对象代码。
我认为“静态内联”的做法是一样的(不一定内联),但内联时不会生成可链接的对象代码(因为没有其他模块可以链接到它)。
“extern inline”在哪里适合图片?
假设我想用一个内联函数replace一个预处理macros,并且要求这个函数被内联(例如,因为它使用__FILE__和__LINE__macros,这个macros应该为调用者parsing而不是这个被调用的函数)。 也就是说,如果函数没有被内联,我想看到一个编译器或链接器错误。 “extern inline”是否这样做? (我假设,如果没有,除了坚持使用macros之外,没有办法实现这种行为。)
C ++和C有区别吗?
不同的编译器厂商和版本有区别吗?
在K&R C或C89中,内联不是该语言的一部分。 许多编译器将它作为扩展来实现,但没有关于它如何工作的定义的语义。 海湾合作委员会是第一个实施内联,并引入inline
, static inline
和外extern inline
构造; 大多数C99前期编译器一般都会跟着领先。
GNU89:
-
inline
:函数可以内联(虽然只是一个提示)。 一个非线性版本总是发出并且在外部可见。 因此,只能在一个编译单元中定义这样的内联,而其他每个单元都需要将其视为一个外联函数(或者在链接时会得到重复的符号)。 -
extern inline
不会生成外extern inline
版本,但可能会调用其中一个(因此您必须在其他编译单元中定义该定义)。但是,单定义规则适用,但是外联版本必须具有相同的代码如同在这里提供的内联,以防编译器调用它。 -
static inline
不会生成一个外部可见的超线程版本,尽pipe它可能会生成一个静态的文件。 单一定义规则不适用,因为从来没有发出外部符号,也没有呼叫。
C99(或GNU99):
-
inline
:像GNU89“extern inline”; 没有外部可见的function被发射,但是可能被调用,因此必须存在 -
extern inline
:像GNU89“inline”:发出外部可见的代码,所以至多有一个翻译单元可以使用它。 -
static inline
:像GNU89“静态内联”。 这是gnu89和c99之间唯一的便携式
C ++:
内联函数必须内联无处不在,定义相同。 编译器/链接器将整理符号的多个实例。 没有static inline
或外extern inline
定义,尽pipe许多编译器都有它们(通常遵循gnu89模型)。
我相信你误解了__FILE__和__LINE__基于这个声明:
因为它使用了__FILE__和__LINE__这些macros来parsing调用者,而不是这个被调用的函数
编译有几个阶段,预处理是第一个阶段。 __FILE__和__LINE__在该阶段被replace。 所以编译器可以考虑内联的函数,它们已经被replace了。
这听起来像你试图写这样的东西:
inline void printLocation() { cout <<"You're at " __FILE__ ", line number" __LINE__; } { ... printLocation(); ... printLocation(); ... printLocation();
并希望每次都能得到不同的值。 正如唐所说,你不会,因为__FILE__和__LINE__是由预处理器实现的,但内联是由编译器实现的。 所以无论你从哪里调用printLocation,你都会得到相同的结果。
你可以得到这个工作的唯一方法是使printLocation成为一个macros。 (是的我知道…)
#define PRINT_LOCATION {cout <<"You're at " __FILE__ ", line number" __LINE__} ... PRINT_LOCATION; ... PRINT_LOCATION; ...
内联,静态内联和外联内联的情况很复杂,至less因为gcc和C99为它们的行为(大概是C ++)定义了一些不同的含义。 你可以在这里find一些有用和详细的信息。
macros是你的select,而不是内联函数。 macros在内存函数中的一个罕见场合。 尝试以下:我写了这个“MACRO MAGIC”代码,它应该工作! testing了gcc / g ++ Ubuntu 10.04
//(c) 2012 enthusiasticgeek (LOGGING example for StackOverflow) #ifdef __cplusplus #include <cstdio> #include <cstring> #else #include <stdio.h> #include <string.h> #endif //=========== MACRO MAGIC BEGINS ============ //Trim full file path #define __SFILE__ (strrchr(__FILE__,'/') ? strrchr(__FILE__,'/')+1 : __FILE__ ) #define STRINGIFY_N(x) #x #define TOSTRING_N(x) STRINGIFY_N(x) #define _LINE (TOSTRING_N(__LINE__)) #define LOG(x, s...) printf("(%s:%s:%s)" x "\n" , __SFILE__, __func__, _LINE, ## s); //=========== MACRO MAGIC ENDS ============ int main (int argc, char** argv) { LOG("Greetings StackOverflow! - from enthusiasticgeek\n"); return 0; }
对于多个文件,在一个单独的头文件中定义这些macros,在每个c / cc / cxx / cpp文件中都包含相同的macros。 请尽可能使用内联函数或常量标识符(视情况需要)。