Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's the purpose of -Wbad-function-cast, why does it only apply to the direct return value?

Tags:

c

gcc-warning

There's a rationale for the warning here, but that fails to answer the whole picture. For example the following code triggers the warning:

(int)round(M_PI);

but on the other hand the following code doesn't:

double d;
(int)(d = round(M_PI));

this doesn't either:

(int)M_PI;

the rationale was that you shouldn't convert to int by simply casting, but you should use round, floor or similar function. However using round will still trigger the warning, but as seen above typecasting a constant or assigned variable doesn't.

So if it's that bad to cast from double to int, then why doesn't the warning trigger when you write (int)d or (int)M_PI? In what way is one supposed to circumvent the warning in case you want to convert the return value? Is there a warning that would handle these perilous conversions in a more correct/reasonable way?

like image 614
skyking Avatar asked Feb 10 '16 06:02

skyking


1 Answers

-Wbad-function-cast (C and Objective-C only)

Warn when a function call is cast to a non-matching type. For example, warn if a call to a function returning an integer type is cast to a pointer type.

As its name suggests, -Wbad-function-cast only warns when you are casting function calls to a non-matching type. It doesn't warn on all casts. This explains why you are not getting that warning for your last two examples:

  • (int)(d = round(M_PI)); doesn't trigger a warning because it is casting double d to int after it has been assigned a value.
  • (int)M_PI; doesn't trigger a warning because M_PI is usually implemented as #define M_PI 3.14159...; it is simply a numeric token and not a function call.

You are right that it could be bad to cast from double to int as you are potentially losing information. You could avoid the GCC warning by simply assigning the function return value to a matching type, then casting later, as in your two examples that don't trigger the warning.

Of course, the point of the warning is not to force you to write extra code to do the same thing. Even for functions that "return an integral value" like round(), the return value may be too big to fit in an int. What you should be doing is checking to see if the value is safe to cast first.

like image 111
congusbongus Avatar answered Nov 15 '22 21:11

congusbongus