未定义行为的定义

时间:2017-05-05 11:04:39

标签: c++ c standards undefined-behavior

我已阅读cppreference关于未定义行为的内容,并了解其中的差异。我没有找到的是隐含的东西。

我希望任何未明确定义的行为都是未指定的行为。但是当我试图在t的格式字符串中找到fopen的含义时,cppreference上没有任何内容,并且它没有说明它是实现定义的。更让我感到困惑的是,在笔记中明确说明了filename参数。

另一方面,msdn定义了t参数,这意味着任何未明确声明为undefined的行为都可以实现定义?或者是cppreference只是错过了一个句子而我只是在追逐幽灵?

我想问题归结为我的问题是,如果没有任何关于某事的内容,是什么,未定义或实现定义的行为?

PS。问题是关于一般情况,所以请不要告诉我如何在答案中使用fopen“正确的方法”。这个功能只是一个例子。

2 个答案:

答案 0 :(得分:2)

阅读有关未定义/实现定义行为的文档是该语言的相关标准;例如,对于C,最新的标准文件是" ISO / IEC 9899:2011",也称为C11。由于这些不是公开的,我们经常使用最后的公共工作草案。对于C11,最后的公共工作草案是n1570,至少在port70.net可用。

C11标准明确说明了以下"未定义的行为":

  

1在本国际标准中,''''''应被解释为对实施或计划的要求;相反,'''''''''被解释为禁止。

     

2如果 要求出现在约束或运行时约束之外,则行为未定义。未定义的行为在本国际标准中以未定义的行为表示,忽略任何明确的行为定义。这三者之间的重点没有区别;它们都描述了未定义的行为

因此,当涉及到标准时,标准中未明确定义的任何行为都是未定义的,并且每种可能的可想象和难以想象的行为都是可以接受的。

现在,不同的实现,如MSVC或GCC可以为某些构造提供更强的保证 - 它们可以记录在该实现中可以预期某种行为。但是,如果想要编写便携式 C代码,则应避免依赖此类行为。

至于fopenC11 7.21.5.3p3)表示

  

参数模式指向一个字符串。如果字符串是以下之一,则文件以指示的模式打开。 否则,行为未定义。

(强调我的)

该列表仅包含rwwxarbwbwbxabr+w+w+xa+r+brb+w+b,{{ 1}},wb+w+bxwb+xa+b;因此,给定一个带有ab+的模式字符串,特定的t实现可以自由地执行它认为合适的任何内容,包括:

  • 以文本模式打开文件
  • 以二进制模式打开文件
  • 打开文件以追加
  • 崩溃
  • t 运行文件
  • 返回错误
  • 将透明 t 翻译的文件打开到 T urkish
  • 或任何其他行为

然而,实施仍然可以符合标准。

答案 1 :(得分:2)

如果未指定任何行为,则行为未定义。这由未定义行为的定义(C11)保证:

  

3.4.3
  未定义的行为
  在使用不可移植或错误的程序结构或错误数据时,这种行为   国际标准没有要求

与关于一致性的第4章§2一起:

  

如果''''或'''''''要求出现在a。之外   违反约束或运行时约束,行为是   未定义。此处另有说明未定义的行为   国际标准用''未定义的行为''或由   省略任何明确的行为定义。没有   这三者之间的重点不同;他们都描述了''行为   这是未定义的''。

至于您的具体示例,它不适用于此处,因为fopen明确表示未知格式会给出未定义的行为。 fopen函数在C11 7.21.5.3中指定:

  

参数mode指向一个字符串。如果字符串是以下之一,则文件以指示的模式打开。否则,行为未定义。“

(允许的格式列表如下)