拿这个代码:
int issuecode(int i)
{
return 2 * i;
}
int main(int argc, char **argv)
{
return issuecode(argc);
}
我理解它的方式,如果编译为 C 程序,它将具有未定义的行为。我根据这些标准报价进行推理:
C99, 7.26 (或 C11, 7.31)
为方便起见,以下名称分组在各个标题下。无论程序包含什么标头,下面描述的所有外部名称都是保留的。
C99、7.26.2(或 C11、7.31.2)
is
以or和小写字母开头的函数名称to
可以添加到<ctype.h>
标头中的声明中。
C99, 7.1.3 (或 C11, 7.1.3)
每个标头声明或定义其相关子条款中列出的所有标识符,并可选地声明或定义其相关的未来库方向子条款中列出的标识符和始终保留用于任何用途或用作文件范围标识符的标识符。
[...]
- 以下任何子条款(包括未来的库方向)中具有外部链接的所有标识符始终保留用作具有外部链接的标识符。
[...] 如果程序在保留标识符的上下文中声明或定义标识符(7.1.4 允许的除外),或将保留标识符定义为宏名称,则行为未定义。
综上所述,我相信函数名issuecode
实际上是为 in 保留使用的<ctype.h>
,因此该程序在技术上具有 UB。
问题 0(健全性检查):我对标准的解读是否正确,程序的行为在技术上是否未定义?
问题一:程序编译成C++代码会有UB吗?
我相信答案是“不”,因为从下面的引用中,我会说 C 的“未来库方向”不是 C++ 标准库的一部分,但我不太确定。
C++11、21.7
表 74、75、76、77、78 和 79 分别描述了标题
<cctype>
、<cwctype>
、<cstring>
、<cwchar>
、<cstdlib>
(字符转换)和<cuchar>
。这些标头的内容应分别与标准 C 库标头
<ctype.h>
、<wctype.h>
、<string.h>
、<wchar.h>
和<stdlib.h>
以及 C Unicode TR 标头相同,并进行以下修改:
“以下修改”均未提及附加的保留标识符。表 74 是函数名称的分类列表,例如isdigit
和isalnum
。
C++11、C.2
1. 本小节总结了标准 C 库中包含的 C++ 标准库的内容。它还总结了其他子条款(17.6.1.2、18.2、21.7)中提到的标准 C 库中定义、声明或行为的显式更改。
7. C++标准库提供了来自C库的209个标准函数,如表153所示。
同样,表 153 是一个税收清单。
问题 2:假设我在问题 1 上错了,并且程序实际上在 C++ 中也有 UB,那么以下更改是否会影响这一点?
namespace foo {
int issuecode(int i)
{
return 2 * i;
}
}
using namespace foo;
int main(int argc, char **argv)
{
return issuecode(argc);
}
注意:标准引用来自草案 N1256 (C99)、N1570 (C11) 和 N3242 (C++11),它们是各自语言版本的最新公开可用草案。