未定义行为的定义
Definition of Undefined behaviour
我已阅读 cppreference 关于未定义行为的内容并理解其中的区别。我没有找到的是隐含的。
我希望任何未明确定义的行为都是未指定的行为。但是当我试图找到 t
在 fopen
的格式字符串中的含义时,cppreference 中没有任何内容,也没有任何地方声明它是实现定义的。更让我烦恼的是,在注释中明确说明了 filename
参数。
另一方面,msdn 定义了 t
参数,这意味着任何未明确声明为未定义的行为都可以在实现中定义吗?还是cppreference就是少了一句我只追鬼?
我想这个问题归结为我的问题是,如果没有关于某事的任何内容,它是什么,未定义或实现定义的行为?
PS。这个问题是关于一般情况的,所以请不要告诉我如何在答案中使用 fopen
"the right way"。该功能只是一个示例。
要阅读的有关未定义/实现定义行为的文档是该语言的相关标准;例如,对于 C,最新的标准文档是“ISO/IEC 9899:2011”,也称为 C11。由于 public 无法免费获得这些内容,因此我们经常使用最后的 public 工作草案。对于 C11,最后的 public 工作草案是 n1570,它至少在 port70.net.
可用
C11 标准明确说明了以下“未定义行为”:
1 In this International Standard, ''shall'' is to be interpreted as a requirement on an implementation or on a program; conversely, ''shall not'' is to be interpreted as a prohibition.
2 If a shall or shall not requirement that appears outside of a constraint or runtime-constraint is violated, the behavior is undefined. Undefined behavior is otherwise indicated in this International Standard by the words undefined behavior or by the omission of any explicit definition of behavior. There is no difference in emphasis among these three; they all describe behavior that is undefined.
因此,任何未在标准中明确定义的行为,就标准而言,都是未定义的,并且所有可能的可想象和不可想象的行为都同样可以接受。
现在,不同的实现,如 MSVC 或 GCC 可以为某些构造提供更强的保证 - 它们可以记录在该实现中可以预期的特定行为。但是,如果想编写 可移植 C 代码,则应避免依赖这种行为。
至于fopen
,C11 7.21.5.3p3)表示
The argument mode points to a string. If the string is one of the following, the file is open in the indicated mode. Otherwise, the behavior is undefined.
(强调我的)
并且列表仅包含 r
、w
、wx
、a
、rb
、wb
、wbx
, ab
, r+
, w+
, w+x
, a+
, r+b
, rb+
, w+b
, wb+
、w+bx
、wb+x
、a+b
和 ab+
;因此给定一个带有 t
的模式字符串,特定的 fopen
实现可以自由地做任何它认为合适的事情,包括:
- 正在以文本模式打开文件
- 正在以二进制模式打开文件
- 正在打开文件进行追加
- 崩溃
- t运行文件
- 返回错误
- 正在打开一个透明 t 翻译成 Turkish
的文件
- 或任何其他行为
但实现仍然符合标准。
如果根本没有指定行为,则行为未定义。这是由未定义行为(C11)的定义保证的:
3.4.3
undefined behavior
behavior, upon use of a nonportable or erroneous program construct or of erroneous data, for which this
International Standard imposes no requirements
连同第 4 章 2 节有关一致性的内容:
If a ‘‘shall’’ or ‘‘shall not’’ requirement that appears outside of a
constraint or runtime constraint is violated, the behavior is
undefined. Undefined behavior is otherwise indicated in this
International Standard by the words ‘‘undefined behavior’’ or by the
omission of any explicit definition of behavior. There is no
difference in emphasis among these three; they all describe ‘‘behavior
that is undefined’’.
至于您的具体示例,它不适用于此处,因为 fopen
明确表示未知格式会产生未定义的行为。 fopen
函数在C11 7.21.5.3中指定:
The argument mode
points to a string. If the string is one of the following, the file is open in the indicated mode. Otherwise, the behavior is undefined."
(允许的格式列表如下)
我已阅读 cppreference 关于未定义行为的内容并理解其中的区别。我没有找到的是隐含的。
我希望任何未明确定义的行为都是未指定的行为。但是当我试图找到 t
在 fopen
的格式字符串中的含义时,cppreference 中没有任何内容,也没有任何地方声明它是实现定义的。更让我烦恼的是,在注释中明确说明了 filename
参数。
另一方面,msdn 定义了 t
参数,这意味着任何未明确声明为未定义的行为都可以在实现中定义吗?还是cppreference就是少了一句我只追鬼?
我想这个问题归结为我的问题是,如果没有关于某事的任何内容,它是什么,未定义或实现定义的行为?
PS。这个问题是关于一般情况的,所以请不要告诉我如何在答案中使用 fopen
"the right way"。该功能只是一个示例。
要阅读的有关未定义/实现定义行为的文档是该语言的相关标准;例如,对于 C,最新的标准文档是“ISO/IEC 9899:2011”,也称为 C11。由于 public 无法免费获得这些内容,因此我们经常使用最后的 public 工作草案。对于 C11,最后的 public 工作草案是 n1570,它至少在 port70.net.
可用C11 标准明确说明了以下“未定义行为”:
1 In this International Standard, ''shall'' is to be interpreted as a requirement on an implementation or on a program; conversely, ''shall not'' is to be interpreted as a prohibition.
2 If a shall or shall not requirement that appears outside of a constraint or runtime-constraint is violated, the behavior is undefined. Undefined behavior is otherwise indicated in this International Standard by the words undefined behavior or by the omission of any explicit definition of behavior. There is no difference in emphasis among these three; they all describe behavior that is undefined.
因此,任何未在标准中明确定义的行为,就标准而言,都是未定义的,并且所有可能的可想象和不可想象的行为都同样可以接受。
现在,不同的实现,如 MSVC 或 GCC 可以为某些构造提供更强的保证 - 它们可以记录在该实现中可以预期的特定行为。但是,如果想编写 可移植 C 代码,则应避免依赖这种行为。
至于fopen
,C11 7.21.5.3p3)表示
The argument mode points to a string. If the string is one of the following, the file is open in the indicated mode. Otherwise, the behavior is undefined.
(强调我的)
并且列表仅包含 r
、w
、wx
、a
、rb
、wb
、wbx
, ab
, r+
, w+
, w+x
, a+
, r+b
, rb+
, w+b
, wb+
、w+bx
、wb+x
、a+b
和 ab+
;因此给定一个带有 t
的模式字符串,特定的 fopen
实现可以自由地做任何它认为合适的事情,包括:
- 正在以文本模式打开文件
- 正在以二进制模式打开文件
- 正在打开文件进行追加
- 崩溃
- t运行文件
- 返回错误
- 正在打开一个透明 t 翻译成 Turkish 的文件
- 或任何其他行为
但实现仍然符合标准。
如果根本没有指定行为,则行为未定义。这是由未定义行为(C11)的定义保证的:
3.4.3
undefined behavior
behavior, upon use of a nonportable or erroneous program construct or of erroneous data, for which this International Standard imposes no requirements
连同第 4 章 2 节有关一致性的内容:
If a ‘‘shall’’ or ‘‘shall not’’ requirement that appears outside of a constraint or runtime constraint is violated, the behavior is undefined. Undefined behavior is otherwise indicated in this International Standard by the words ‘‘undefined behavior’’ or by the omission of any explicit definition of behavior. There is no difference in emphasis among these three; they all describe ‘‘behavior that is undefined’’.
至于您的具体示例,它不适用于此处,因为 fopen
明确表示未知格式会产生未定义的行为。 fopen
函数在C11 7.21.5.3中指定:
The argument
mode
points to a string. If the string is one of the following, the file is open in the indicated mode. Otherwise, the behavior is undefined."
(允许的格式列表如下)