返回过程是否根据C标准转换/转换结果所需的类型,或者仅在某些实现中支持?

我注意到了

float f; [..] printf("%i\n", f); 

不合理

 printf("%i\n", (int)f); 

但是也

 int func(float f) { return f; } 

好的

 printf("%i\n", func(f)); 

是由返回流程或标准支持的function完成的转换/转换,还是理想的需要

 int func(float f) { return (int) f; } 

转换是标准的。 ISO C99标准的相关部分见6.8.6.4节第3段:

如果表达式的类型与其出现的函数的返回类型不同,则转换该值,就好像通过赋值给具有函数返回类型的对象一样。

所以它被隐式转换,就像它在这个赋值中一样:

 float f = 3.0f; int i; i = f; 

允许的转化次数为:

  • 返回类型具有限定或非限定算术类型,表达式具有算术类型;
  • 返回类型具有与表达式类型兼容的结构或联合类型的限定或非限定版本;
  • 返回类型和表达式都是兼容类型的限定或非限定版本的指针,返回类型具有表达式类型的所有限定符;
  • 返回类型或表达式之一是指向对象或不完整类型的指针,另一个是指向void的限定或非限定版本的指针,返回类型具有表达式类型的所有限定符;
  • 返回类型是一个指针,表达式是一个空指针常量; 要么
  • 返回类型的类型为_Bool ,表达式是指针。

(您的示例与第一个匹配 – intfloat都是算术类型)

通常,当表达式具有某种数字类型,并且其上下文需要不同的数字类型时,将自动进行适当的转换。 这适用于以下情况:

 void f(float); void g(long); int i = 3; f(i); /*function call, with a prototype in scope*/ g(i); /*ditto*/ double d = i; /*assignment*/ 

该原则也适用于表达式return指令。

该原理不适用于printf等可变函数。 原因是正确的转换取决于格式字符串,编译器不需要分析格式字符串; 实际上,如果格式不是字符串文字,编译器通常无法对其进行分析。 因此,在以下printf调用中,所有强制转换都是必需的:

 int i = 3; float f = 1.5; printf("%ld %f %d\n", (long)i, (double)i, (int)f); 

但是,由于促销( charshort被提升为intfloat被提升为double )以及%c期望int的事实,在以下printf调用中没有任何强制转换:

 char c = 'a'; float f = 1.5; printf("%c %d %f", c, c, f);