C和C++标准之间的关系是什么?

43

我在写这篇答案时引用了http://en.cppreference.com/w/cpp/string/byte/tolower#Parameters的内容。

如果字符既不是无符号字符,也不是 EOF,那么其行为未定义。

当我查看添加此短语的编辑历史时,我发现作者的评论如下:

根据 C99 7.4/1,不能将带有负值的有符号字符用于任何 ctype.h 函数。

作者在 C++ 文档中引用了 C99 标准。这是有效的吗?我没有找到关于该函数定义的 C++ 标准,因此必须假定它是有效的。

但这让我担心两个问题:

  1. 我怎样才能知道 C++ 标准依赖于哪个版本的 C 标准?
  2. 到处都有关于C 和 C++ 差异的列表。如果我查看 C 标准并参考 C++,我怎么可能知道我正在查看的区域是否已被覆盖?

1
就此而言,第一个描述“不能表示为无符号字符…”是对C99和C11要求的相当近似的解释。作者的评论“不能使用负无符号字符…”是错误的(更不用说自相矛盾了)。很抱歉让事情变得混乱;我第一次没有仔细阅读你的问题。 - Pete Becker
糟糕,第二条评论引用错误:应该是“负有符号字符”,而不是“负无符号字符”。尽管如此,“负有符号字符”是完全错误的,因为不可表示为有符号字符的负值也被禁止,并且可能作为负有符号字符表示的EOF是允许的。 - Pete Becker
相关,如果不是重复的话:https://dev59.com/RFsX5IYBdhLWcg3wCLyx#34308279 - dhein
@PeteBecker 这是我的提交注释,我指的是我将 \xb4 更改为无符号(同时添加了有关 UB 的提及)。但是没错,它不够啰嗦。 - Cubbi
3个回答

36

第一个问题:

C++标准在其“规范参考”部分明确列出了其依赖的C标准。对于C++14,[intro.refs] 1.2/1 列出了 C99:

  • ISO/IEC 9899:1999,Programming languages — C
  • ISO/IEC 9899:1999/Cor.1:2001(E),Programming languages — C, Technical Corrigendum 1
  • ISO/IEC 9899:1999/Cor.2:2004(E),Programming languages — C, Technical Corrigendum 2
  • ISO/IEC 9899:1999/Cor.3:2007(E),Programming languages — C, Technical Corrigendum 3

第二个问题:

C++标准没有隐式地包含 C 标准中的任何部分; 所有对 C 标准的引用都是显式的。 Annex C,“Compatibility” 是关于 C++ 标准与 C 标准差异的好的信息来源,特别是 C.1 [diff.iso]。

此外,对 C 标准库的引用分散在 C++ 标准库的描述中(在 C++14 的第17到30章)。特别感兴趣的是:

  • 17.2 [library.c],描述了 C 标准库的基本包含
  • 第18章 [language.support],描述了 C++ 标准库中许多 <c:::> 头文件(提供 C 标准库功能)。

14
在C++14中,它依赖于ISO / IEC 9899:1999(加上三个勘误,因此本质上是C99),如N4140中的1.2 [intro.refs]所述。在C++98中,它是C90,在C++17中,它可能是C11,但C++标准将始终明确说明。如果您正在参考C标准以供C++使用,您如何知道我正在查看的区域是否被覆盖?您可以查看C++标准,它明确导入了不包括“restrict”在内的C定义或任何C行为,或者进行明确修改。通常,阅读良好的文档而不是标准本身将对您产生足够的帮助。
回答您最初的问题:作者在C ++文档中引用了C99标准,这有效吗?是的,因为表格74 [包含,me]、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头文件<uchar.h>的内容相同。以下修改不适用于std::tolower函数,我(译者)排除在外:

N4140中的21.8 [c.strings]


2
这些是非常微妙的问题。请问,除非成为标准委员会的成员,或者至少是一位拥有数千万行成功代码的受人尊敬的作者,否则如何区分“阅读好的文档而不是标准本身”?谢谢,@Baum mit Augen - user3078414
7
我的经验法则是:如果我需要查看标准本身才能确定我的代码是否有效,那么它就太复杂或者太智能了。我通常需要使用标准来处理一些我无法控制的事情,比如检查cppr上的文档正确性(很少出现),或者在一些“只是为了好玩”的情况下验证一些行为,比如在SO和错误报告中。对于真正的代码,文档是你的朋友。cppr通常是正确的,并引用标准中的来源。 - Baum mit Augen
5
对于标记为“language-lawyer”的Stack Overflow问题,当然只有标准本身才是最重要的,但这只是其中一件有趣的事情。 - Baum mit Augen

3
编辑是正确的,这个特定的文本从C90起就成为标准了。
来自C90 4.3:

头文件“ctype.h”声明了几个函数,用于测试和映射字符。在所有情况下,参数都是int类型,其值应可表示为无符号字符或等于宏EOF的值。如果参数具有任何其他值,则行为是未定义的。

来自C11 7.4/1:

头文件“ctype.h”声明了几个有用于分类和映射字符的函数。在所有情况下,参数都是int类型,其值应可表示为无符号字符或等于宏EOF的值。如果参数具有任何其他值,则行为是未定义的。

相同的文本;C一直都是这样的。所以不管你使用的是哪个C++版本,因为所有的C版本都是相等的,所以并不重要。

1
挑剔一下:4.3是C89(ISO之前)的编号。C90将其改为7.3。 - Cubbi
@Cubbi 这是来自于其中一个“X3” C89 标准,我无法获取 ISO C90。 - Lundin

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接