定义一个返回不兼容类型但无法访问的函数

ano*_*nol 2 c c99 language-lawyer

阅读完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;
}
Run Code Online (Sandbox Code Playgroud)

特别是,应该定义该程序的行为,因为返回值是(a)从未达到过的,并且(b)从未使用过,即使它已达到.

尽管如此,我的大多数编译器(GCC,Clang和CompCert)都会阻止编译此程序,但会出错returning 'struct s' from a function with incompatible result type 'int'.我确实设法编译它tcc,但我不知道它是否主要是由于运气(即缺乏验证).

有人可以确认这个程序在语法上是否有效C99,以及它的行为是否完全明确,或者说明标准禁止它的位置?

我实际上更喜欢我的编译器拒绝它,但是例如一些宏定义可以产生类似于这个的代码,所以如果它们是有效的,接受这些程序实际上是有用的.

背景

下面是我可以找到的C99标准的可能相关的摘录,以及我为什么不应该禁止我的程序在语法上有效和语义定义良好的原因:

§6.8.6.4退货声明

§6.8.6.4.1带有表达式的return语句不应出现在返回类型为void的函数中.不带表达式的return语句只能出现在返回类型为void的函数中.

在我的代码中,我们有一个voidvoid返回的非函数,所以一切似乎都很好.

§6.8.6.4.3如果执行带有表达式的return语句,则表达式的值将作为函数调用表达式的值返回给调用者.如果表达式的类型与其出现的函数的返回类型不同,则通过赋值给具有函数返回类型的对象来转换该值.

因为从不执行return语句,所以不适用.

§6.9.1函数定义

§6.9.1.12如果到达了终止函数的},并且调用者使用了函数调用的值,则行为是未定义的.

调用者不使用函数调用的结果,因此应该定义行为.

小智 10

"如果表达式的类型与它出现的函数的返回类型不同,则转换该值就像分配给具有函数返回类型的对象一样." 是一个独立的句子.它不以"如果执行带有表达式的return语句"为条件,因此甚至适用于您的代码.而且我很确定你已经知道转换好像通过赋值意味着不兼容的类型允许编译时错误.