我正在设计一个用于单元测试的微框架,并希望能够为客户提供定义“测试套件名称”的能力。所以我有以下名为 test_suite.h
的头文件:
static const char *const test_suite_name;
static inline void run_all_tests(void){
printf("Running ");
if(!test_suite_name){
printf("unnamed suite");
} else {
printf("%s suite", test_suite_name);
}
//run tests
}
这样做的目的是允许客户端“覆盖”test_suite_name
,如下所示:
#include "test_suite.h"
extern const char *const test_suite_name = "suite1";
我认为这种用法的行为是明确定义的,因为static const char *const test_suite_name;
构成了一个暂定定义,然后extern const char *const test_suite_name = "suite1";
构成外部定义。自 6.2.2(p4)
起不存在链接分歧:
For an identifier declared with the storage-class specifier
extern
in a scope in which a prior declaration of that identifier is visible,31) if the prior declaration specifies internal or external linkage, the linkage of the identifier at the later declaration is the same as the linkage specified at the prior declaration.
我进行了一些实验:
打印以下错误消息:
error: redefinition of 'const char* const suite_name'
extern const char *const suite_name = "some suite";
工作完全正常,没有产生任何警告
gcc7.4.0
在我的机器上。
产生警告:
warning: ‘test_suite_name’ initialized and declared ‘extern’
问题:上面显示的代码的行为定义明确吗?
我很确定如果编写以下内容,行为将是未定义的:
#include "test_suite.h"
const char *const test_suite_name = "suite1"; //without extern
因为6.2.2(p5)
(强调我的):
If the declaration of an identifier for a function has no storage-class specifier, its linkage is determined exactly as if it were declared with the storage-class specifier
extern
. If the declaration of an identifier for an object has file scope and no storage-class specifier, its linkage is external.
因此,我们在具有内部链接的 static const char *const test_suite_name;
和具有外部链接的 const char *const test_suite_name = "suite1";
之间存在链接分歧。
最佳答案
静态的使用
您实际上可以使用静态而不是外部。 Ubuntu下用gcc快速测试一下:
#include "test_suite.h"
static const char *const test_suite_name = "huhu";
int main() {
run_all_tests();
return 0;
}
如果我编译:
gcc -Wall -Wpedantic -Wextra mytest.c -o mytest
它给出输出:
Running huhu suite
省略静态
如果您不小心忘记指定 static,那么它应该会给出编译时错误。因此,如果我将此行更改为:
const char *const test_suite_name = "huhu";
并尝试像这样编译它:
gcc -Wall -Wpedantic -Wextra mytest2.c -o mytest2
将显示此错误消息:
mytest2.c:3:19: error: non-static declaration of ‘test_suite_name’ follows static declaration
const char *const test_suite_name = "huhu";
^~~~~~~~~~~~~~~
In file included from mytest2.c:1:
test_suite.h:3:26: note: previous declaration of ‘test_suite_name’ was here
static const char *const test_suite_name;
由于这是一个错误,如果您使用以下命令进行编译,它也会输出:
gcc mytest2.c -o mytest2
错误消息屏幕截图
关于c - 允许 "overriding"具有内部链接的零初始化对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56365581/