定义返回不兼容类型但无法访问的函数
Defining a function returning incompatible type, but unreachable
通读 C99 标准后,我找不到任何禁止在下面定义函数 f
的部分:
struct s { double d; };
int f() {
if (0) return (struct s){.d = 3.14};
// There is intentionally no return statement of type int, which is valid
}
int main() {
f();
return 0;
}
特别是,应该定义此程序的行为,因为 return 值 (a) 一开始从未达到,并且 (b) 从未使用过,即使达到了也是如此。
尽管如此,我的大多数编译器(GCC、Clang 和 CompCert)都会阻止编译该程序,并出现错误 returning 'struct s' from a function with incompatible result type 'int'
。我确实设法用 tcc
编译了它,但我不知道这是否主要是由于运气(即缺乏验证)。
有人可以确认此程序在语法上是否符合 C99 有效,并且其行为是否完全定义明确,或者以其他方式指出标准禁止的地方?
我实际上更希望我的编译器拒绝它,但是例如一些宏定义可能会产生类似于这个的代码,所以如果它们是有效的,那么接受这样的程序实际上是有用的。
背景
以下是我能找到的可能相关的 C99 标准摘录,以及我为什么不应该禁止我的程序在语法上有效和语义上定义明确的原因:
§6.8.6.4 The return statement
§6.8.6.4.1 A return statement with an expression shall not appear in a function whose return type is void. A return statement without an expression shall only appear in a function whose return type is void.
在我的代码中,我们有一个非 void
函数和一个非 void
return,所以一切看起来都很好。
§6.8.6.4.3 If a return statement with an expression is executed, the value of the expression is returned to the caller as the value of the function call expression. If the expression has a type different from the return type of the function in which it appears, the value is converted as if by assignment to an object having the return type of the function.
因为return语句永远不会执行,所以上面的不适用。
§6.9.1 Function definitions
§6.9.1.12 If the } that terminates a function is reached, and the value of the function call is used by the caller, the behavior is undefined.
函数调用的结果没有被调用者使用,所以应该定义行为。
"If the expression has a type different from the return type of the function in which it appears, the value is converted as if by assignment to an object having the return type of the function." 是一个独立的句子。它不以 "If a return statement with an expression is executed" 为条件,因此甚至适用于您的代码。而且我敢肯定,您已经知道像通过赋值一样进行转换意味着不兼容的类型会导致编译时错误。
通读 C99 标准后,我找不到任何禁止在下面定义函数 f
的部分:
struct s { double d; };
int f() {
if (0) return (struct s){.d = 3.14};
// There is intentionally no return statement of type int, which is valid
}
int main() {
f();
return 0;
}
特别是,应该定义此程序的行为,因为 return 值 (a) 一开始从未达到,并且 (b) 从未使用过,即使达到了也是如此。
尽管如此,我的大多数编译器(GCC、Clang 和 CompCert)都会阻止编译该程序,并出现错误 returning 'struct s' from a function with incompatible result type 'int'
。我确实设法用 tcc
编译了它,但我不知道这是否主要是由于运气(即缺乏验证)。
有人可以确认此程序在语法上是否符合 C99 有效,并且其行为是否完全定义明确,或者以其他方式指出标准禁止的地方?
我实际上更希望我的编译器拒绝它,但是例如一些宏定义可能会产生类似于这个的代码,所以如果它们是有效的,那么接受这样的程序实际上是有用的。
背景
以下是我能找到的可能相关的 C99 标准摘录,以及我为什么不应该禁止我的程序在语法上有效和语义上定义明确的原因:
§6.8.6.4 The return statement
§6.8.6.4.1 A return statement with an expression shall not appear in a function whose return type is void. A return statement without an expression shall only appear in a function whose return type is void.
在我的代码中,我们有一个非 void
函数和一个非 void
return,所以一切看起来都很好。
§6.8.6.4.3 If a return statement with an expression is executed, the value of the expression is returned to the caller as the value of the function call expression. If the expression has a type different from the return type of the function in which it appears, the value is converted as if by assignment to an object having the return type of the function.
因为return语句永远不会执行,所以上面的不适用。
§6.9.1 Function definitions
§6.9.1.12 If the } that terminates a function is reached, and the value of the function call is used by the caller, the behavior is undefined.
函数调用的结果没有被调用者使用,所以应该定义行为。
"If the expression has a type different from the return type of the function in which it appears, the value is converted as if by assignment to an object having the return type of the function." 是一个独立的句子。它不以 "If a return statement with an expression is executed" 为条件,因此甚至适用于您的代码。而且我敢肯定,您已经知道像通过赋值一样进行转换意味着不兼容的类型会导致编译时错误。