return
研究在函数void
和非C 标准void
中滥用语句的后果,我意识到它没有指定当非函数使用空语句或函数使用非空语句时会发生什么:void
return
void
return
int devolver_entero() { return; } // no-void usa una return vacio
我能够在标准中找到以下内容(翻译是我的):
6.8.6.4 返回语句
限制
- 带有表达式的语句
return
不得出现在返回类型为 的函数中void
。没有表达式的语句return
只能出现在返回类型为 的函数中void
。
上面的标准引用说明了应该对 return 和 non-return 函数的语句做什么return
,但在标准的其他地方它说明了不遵循约束时会发生什么:
6.9.1 函数定义
- 如果到达函数终止符
}
并且调用者使用了函数调用的值,则行为未定义。
上面的标准引用表明,如果使用到达右括号的函数的返回值,则会产生未定义的行为}
,因此以下示例具有未定义的行为:
int comportamiento_indefinido(int x) { if (x) return x; }
printf("%d", comportamiento_indefinido(1)); // Correcto
printf("%d", comportamiento_indefinido(0)); // Comportamiento indefinido
在调用comportamiento_indefinido(1)
中,函数通过条件下1
的语句返回;在调用中,条件不满足并且函数在到达右大括号时结束,使用调用的返回是未定义的行为(但使用 is not 的返回)。但是在这种情况下会发生什么?return
if (x)
comportamiento_indefinido(0)
if (x)
}
comportamiento_indefinido(0)
comportamiento_indefinido(1)
int comportamiento_indefinido(int x) { if (x) return; } // return vacio
printf("%d", comportamiento_indefinido(1)); // Comportamiento indefinido?
printf("%d", comportamiento_indefinido(0)); // Comportamiento indefinido
在前面的示例中,调用comportamiento_indefinido(1)
不符合§6.9.1/12
实现未定义行为的指示,因为函数在没有到达右大括号的情况下结束}
并且也不返回任何值。
C 标准的哪一部分考虑到了这一点?
1或者至少我找不到它。
我发现这个问题非常有趣且相关。例如,一个人并不总是能够更正代码,但了解它的作用会很有趣。例如,知道它是否是一个安全漏洞。
在我看来,可以理解为这两种情况是等价的。实际上,作为一个“
no debe
”,如果它是严格的 C99,它就不必编译,对吧?因为否则它应该说“no debería
”。由于原始标准(英文)说:同样的标准说(我的粗体):
也就是说,如果它没有说明行为,那么它就是 undefined。
大多数时候会发生什么?我想对于编译器来说它是等价的,因为在大多数平台上,一个
return
no 表达式编译为ret
(或等价于),就像 put none 一样。使用参数时,它变成移动到寄存器或将表达式的结果压入堆栈,然后返回。例如,areturn 8;
可以是 amov ax,8
或 apush 8
之前ret
。如果在 C 中没有指定return
,编译器仍然必须ret
在汇编程序中包含 a,无论函数是否具有类型,就好像它已经被制作了一样return;
。你懂我的意思么?已编辑:我删除了对另一个 RFC 的引用以及关于事实上的标准的考虑,发现相同的标准定义了它。
(西班牙语)换句话说,如果一个程序不满足标准的限制,由shall(= must)或shall not(= must not)表示,则该程序包含未定义的行为。
正如@ESL 引用的那样:
(西班牙语)也就是说,如果一个函数
void
试图返回一些东西(return expr;
),或者如果一个函数的类型不是void
试图返回任何东西(return;
),那么行为是未定义的(未定义的行为)。在您的情况下,由于您的语句
return
在需要返回值的函数中没有值出现,因此根据第4.2点,它是未定义的行为。相反,这也将是未定义的行为:
这些定义来自: