我已阅读cppreference关于未定义行为的内容,并了解其中的差异。我没有找到的是隐含的东西。
我希望任何未明确定义的行为都是未指定的行为。但是当我试图在t
的格式字符串中找到fopen
的含义时,cppreference上没有任何内容,并且它没有说明它是实现定义的。更让我感到困惑的是,在笔记中明确说明了filename
参数。
另一方面,msdn定义了t
参数,这意味着任何未明确声明为undefined的行为都可以实现定义?或者是cppreference只是错过了一个句子而我只是在追逐幽灵?
我想问题归结为我的问题是,如果没有任何关于某事的内容,是什么,未定义或实现定义的行为?
PS。问题是关于一般情况,所以请不要告诉我如何在答案中使用fopen
“正确的方法”。这个功能只是一个例子。
答案 0 :(得分:2)
阅读有关未定义/实现定义行为的文档是该语言的相关标准;例如,对于C,最新的标准文件是" ISO / IEC 9899:2011",也称为C11。由于这些不是公开的,我们经常使用最后的公共工作草案。对于C11,最后的公共工作草案是n1570,至少在port70.net可用。
C11标准明确说明了以下"未定义的行为":
1在本国际标准中,''''''应被解释为对实施或计划的要求;相反,'''''''''被解释为禁止。
2如果 或不要求出现在约束或运行时约束之外,则行为未定义。未定义的行为在本国际标准中以未定义的行为或表示,忽略任何明确的行为定义。这三者之间的重点没有区别;它们都描述了未定义的行为。
因此,当涉及到标准时,标准中未明确定义的任何行为都是未定义的,并且每种可能的可想象和难以想象的行为都是可以接受的。
现在,不同的实现,如MSVC或GCC可以为某些构造提供更强的保证 - 它们可以记录在该实现中可以预期某种行为。但是,如果想要编写便携式 C代码,则应避免依赖此类行为。
至于fopen
,C11 7.21.5.3p3)表示
参数模式指向一个字符串。如果字符串是以下之一,则文件以指示的模式打开。 否则,行为未定义。
(强调我的)
该列表仅包含r
,w
,wx
,a
,rb
,wb
,wbx
, ab
,r+
,w+
,w+x
,a+
,r+b
,rb+
,w+b
,{{ 1}},wb+
,w+bx
,wb+x
和a+b
;因此,给定一个带有ab+
的模式字符串,特定的t
实现可以自由地执行它认为合适的任何内容,包括:
然而,实施仍然可以符合标准。
答案 1 :(得分:2)
如果未指定任何行为,则行为未定义。这由未定义行为的定义(C11)保证:
3.4.3
未定义的行为
在使用不可移植或错误的程序结构或错误数据时,这种行为 国际标准没有要求
与关于一致性的第4章§2一起:
如果''''或'''''''要求出现在a。之外 违反约束或运行时约束,行为是 未定义。此处另有说明未定义的行为 国际标准用''未定义的行为''或由 省略任何明确的行为定义。没有 这三者之间的重点不同;他们都描述了''行为 这是未定义的''。
至于您的具体示例,它不适用于此处,因为fopen
明确表示未知格式会给出未定义的行为。 fopen
函数在C11 7.21.5.3中指定:
参数
mode
指向一个字符串。如果字符串是以下之一,则文件以指示的模式打开。否则,行为未定义。“
(允许的格式列表如下)