缺少具有非保留标识符的对象/函数的定义是否应导致诊断?

人气:832 发布:2022-10-16 标签: linker c language-lawyer libc linker-errors

问题描述

示例代码:

void accept(int x);

int main(void)
{
        accept(0);
        return 0;
}

调用:

$ gcc t719.c -std=c11 -pedantic -Wall -Wextra
<nothing>

$ clang t719.c -std=c11 -pedantic -Wall -Wextra
<nothing>

$ cl t719.c /std:c11 /Za
t719.obj : error LNK2019: unresolved external symbol accept referenced in function main

$ icc t719.c -std=c11 -pedantic -Wall -Wextra
<nothing>
假设用户忘记定义accept。我们看到可能不会产生任何诊断结果。是否需要诊断?

更新:另一个例子:

extern int y0;

int main(void)
{
        return y0;
}

# linux (begin)
$ gcc t719.c -std=c11 -pedantic -Wall -Wextra
undefined reference to `y0'

$ clang t719.c -std=c11 -pedantic -Wall -Wextra
undefined reference to `y0'

$ icc t719.c -std=c11 -pedantic -Wall -Wextra
<nothing>
# program returned: 243
# linux (end)

# windows (begin)
# gcc in cygwin
$ gcc t719.c -std=c11 -pedantic -Wall -Wextra
<nothing>
# program returned: 255

# clang in cygwin
$ clang t719.c -std=c11 -pedantic -Wall -Wextra
<nothing>
# program returned: 255

$ cl t719.c /std:c11 /Za
unresolved external symbol _y0 referenced in function _main

$ LLVM/12.0.0/bin/clang t719.c -std=c11 -pedantic -Wall -Wextra
<nothing>
# program returned: 72

$ icl -Qstd=c11 t719.c 
<nothing>
# program returned: 65
# windows (end)

推荐答案

C 2018§6.9?5表示:

…如果在表达式中使用使用外部链接声明的标识符(不是作为结果为整数常量的sizeof_Alignof运算符的操作数的一部分),则在整个程序中的某个地方应该正好有一个该标识符的外部定义;…

由于违反了"应当",但它不在约束段落中,因此C 2018§4?2将此行为定义为未定义:

如果出现在约束之外的要求或运行时约束被违反,则行为是未定义的…

关于诊断的条款§5.1.1.3不要求对此进行诊断:

如果预处理翻译单元或翻译单元违反任何语法规则或约束,则一致性实现应至少生成一条诊断消息(以实现定义的方式标识),即使该行为也被明确指定为未定义或实现定义的。在其他情况下不需要生成诊断消息。

651