C标准库可扩展性对C++程序有多大影响?

Rei*_*ica 14 c c++ reserved-words undefined-behavior language-lawyer

拿这个代码:

int issuecode(int i)
{
  return 2 * i;
}

int main(int argc, char **argv)
{
  return issuecode(argc);
}
Run Code Online (Sandbox Code Playgroud)

我理解它的方式,如果编译为C程序,它将具有未定义的行为.我的理由基于这些标准报价:

C99,7.26(或C11,7.31)

为方便起见,以下名称分组在各个标题下.无论程序包含哪些标题,下面描述的所有外部名称都是保留的.

C99,7.26.2(或C11,7.31.2)

is或开头的函数名称to和小写字母可以添加到<ctype.h>标题中的声明中.

C99,7.1.3(或C11,7.1.3)

  1. 每个标头声明或定义其关联子条款中列出的所有标识符,并可选地声明或定义其关联的未来库方向子条款和标识符中列出的标识符,这些标识符始终保留用于任何用途或用作文件范围标识符.

    [...]

    • 所有以下子条款中包含外部链接的标识符(包括未来的库方向)始终保留用作具有外部链接的标识符.
  2. [...]如果程序在保留它的上下文中声明或定义标识符(除了7.1.4允许的标识符),或者将保留标识符定义为宏名称,则行为是未定义的.

基于以上所述,我认为函数名issuecode实际上是保留用于<ctype.h>,因此该程序在技术上具有UB.

问题0(健全性检查):我的标准读数是否正确,程序的行为在技术上是不确定的?

问题1:如果编译为C++代码,程序是否会有UB?

我相信答案是"不",如下面的引言所示,我会说C的"未来图书馆方向"不是C++标准库的一部分,但我不太确定.

C++ 11,21.7

  1. 表74,75,76,77,78,和79描述头<cctype>,<cwctype>,<cstring>,<cwchar>,<cstdlib>(字符转换),和<cuchar>分别.

  2. 这些标头的内容应是相同的标准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);
}
Run Code Online (Sandbox Code Playgroud)

注意:标准报价取自草案N1256(C99),N1570(C11)和N3242(C++ 11),它们是各种语言版本的最新公开草案.

Mge*_*etz 1

为了方便起见,以下名称分组在各个标题下。无论程序包含什么标头,下面描述的所有外部名称都会被保留。

有一个预定义的保留函数列表,如果您的函数不存在名称冲突,则没有问题。

以 is 或 to 开头的函数名称以及小写字母可以添加到 <ctype.h> 标头中的声明中。

可以将操作术语添加到<ctype.h>标题中。“是或到”位只是声明组织的指导。

所以那里从来没有真正的未定义行为......

至于C++,我认为这遵循相同的想法,例如:

namespace foo{
  int isupper ( int c );
}

#include <cctype>
using namespace foo;
int main(void){
    isupper(92);
}
Run Code Online (Sandbox Code Playgroud)

这应该会产生编译器错误,因为您的函数在名称方面与 C 函数发生冲突,但由于命名空间,可以通过在调用开头附加 an或std::a来轻松修复此问题。foo::