Does the return process / convert the type necessary for the result in accordance with the C standard, or is supported only in certain implementations?

I noticed that

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

not reasonable

but

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

is an

but also

 int func(float f) { return f; } 

ok on

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

This conversion / casting performed by the return process or a function supported by the standard, or ideally needs

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

?

+4
source share
2 answers

Conversion is standard. The relevant part of ISO C99 is given in section 6.8.6.4, clause 3:

If the expression has a type from the return type of the function in which it appears, the value is converted as if by assigning an object having the return type of the function.

Thus, it is implicitly converted in the same way as in this assignment:

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

Conversions Allowed:

  • the return type has a qualified or unskilled arithmetic type, and the expression has an arithmetic type;
  • the return type has a qualified or unskilled version of the structure or type of union compatible with the type of expression;
  • the return type and expression are pointers to qualified or unskilled versions of compatible types, and the return type has all the expression type qualifiers;
  • one of the types or return expressions is a pointer to an object or an incomplete type, and the other is a pointer to a qualified or unskilled version of void , and the return type has all the determinants of the type of expression;
  • the return type is a pointer, and the expression is a null pointer constant; or
  • the return type is of type _Bool , and the expression is a pointer.

(Your example matches the first - both int and float are arithmetic types)

+5
source

Usually, when an expression has a specific numeric type, and its context expects another numeric type, the corresponding conversion will happen automatically. This applies in cases such as:

 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*/ 

This principle also applies to the return .

This principle does not apply to variational functions such as printf . The reason is that the correct conversions depend on the format string, and the compiler is not required to parse the format string; in fact, if the format is not a string literal, the compiler usually cannot parse it. So, all throws are needed in the following printf call:

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

However, due to promotions ( char and short rises to int , float advances to double ) and to the fact that %c expects int , there are no throws in the next printf call:

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

All Articles