在一个文件中,我有这个宏:
#if defined(__cplusplus)
#define EXTERN_C extern "C"
#else
#define EXTERN_C extern
#endif
但是在网络上搜索,似乎这种宏定义在C路径上没有
extern
(虽然有一些例子存在)。它们通常成对出现,更类似于EXTERN_C_BEGIN
和EXTERN_C_END
来包装一组声明...并且在C构建中是无操作的。但这意味着在头文件中,你最终得写:
EXTERN_C_BEGIN
extern int x; /* ...but I already said extern... */
void doSomething(int y);
EXTERN_C_END
这是因为
extern "C" int x;
等同于 extern "C" { extern int x; }
,而不是 extern "C" { int x; }
。后者只提供了"C linkage",但没有C extern的历史含义。如果您尝试将单行形式下降到C extern,则无法说 EXTERN_C extern int x;
,编译器将在C++构建中在两个externs-on-one-declaration处发出警告。
由于没有开始/结束形式,这通常意味着需要更多的打字。但是我更喜欢在C情况下向编译器发出“意图声明”:
EXTERN_C int x;
EXTERN_C void doSomething(int y); /* does `extern` help the C case? */
我无法立即创造一个好的情景来证明在C中使用函数声明上的extern有助于捕获错误。但直觉上,这种冗余可能具有价值,并且正如我所说,必须在事物上加上“extern”并稍后仍然放置“extern”感觉很尴尬。
优先选择(或避免)哪种方法的原因是什么?
EXTERN_C
、EXTERN_C_BEGIN
和EXTERN_C_END
,其中EXTERN_C
是单个声明的前缀(例如EXTERN_C void function(void);
),而在一组声明之前使用EXTERN_C_BEGIN
,在一组声明之后使用EXTERN_C_END
。在 C 中,由于函数声明默认为extern
类型,因此可以使用空替换EXTERN_C
。在 C 代码中不会使用extern
来表示EXTERN_C_BEGIN
,因为这很容易引入错误。 - Jonathan LefflerEXTERN_C extern int x;
—它可能不会失败,但这并非必要。对于例如:EXTERN_C_BEGIN
/#include "c-header.h"
/EXTERN_C_END
这样的情况,需要使用#define EXTERN_C_BEGIN extern "C" {
和#define EXTERN_C_END }
来包装头文件。 - Jonathan Lefflerextern "C"
和extern
是不同的东西,它们碰巧共享一个关键字。extern "C" { int x; }
与extern "C" { extern int x; }
不同。 - M.Mextern "C"
和extern
是不同的东西,只是碰巧共享一个关键字。 也许是这样,但在使用这个宏时只有一个意图:“我正在编写可以在C或C++下编译的定义,这个声明是外部的,并且应该具有C链接。” 如果语言的细微差别可以折叠成一个有用的宏来做正确的事情,那似乎是一个值得追求的目标。如果不能做到,了解为什么不能做到是很有启示性的。 - HostileFork says dont trust SE