I have written a library in C that now is going to be used in an embedded processor board. I need to reduce the memory foot print so was going an changing the return type of some functions from int to char (only used to flag errors).
Changing the return type but not changing the variable returned doesn't produce a warning. Is there some way set this in gcc as I want to ensure I've caught all instances.
char processSomething (SomeType *something)
{
int result = 0;
...
do stuff
...
return result; /* no warning */
}
Thanks
19 June: I've added the -Wconversion which has highlighted some interesting things. Two questions with this. One of my functions I take a two character hex string and convert to decimal using
char decimal;
decimal = hexstring [0] - '0' << 4 + hexstring [1] - '0'; // for 0 to 9
it complains about converting from int to char and from what I can gather is the '-', '+', and '<<' operators all seem to implicitly convert to int. Is this correct or am I interpreting the warning wrong. Or is there a more better way to do this?
Also, when using strtol into an int (complains about 'long int' to 'int') but I can guarantee the value will not be over even short int in size, is it safe to typecast? As in will it truncate the extra (and hopefully zero bytes) of the long? Or does this depend on endianness?
Thanks
To enable all warnings, use following list of warnings (probably some warnings are duplicated, because I didn't bother to filter warnings enabled by -Wall ). Show activity on this post. Someone has created a set of tools for determining the complete set of warnings for a given GCC or Clang version.
You can use the -Werror compiler flag to turn all or some warnings into errors. Show activity on this post. You can use -fdiagnostics-show-option to see the -W option that applies to a particular warning.
If -Wfatal-errors is also specified, then -Wfatal-errors takes precedence over this option. Inhibit all warning messages. Make all warnings into errors.
You can use a #pragma warning directive to control the level of warning that's reported at compile time in specific source files. Warning pragma directives in source code are unaffected by the /w option.
In this specific case -Wconversion should give you the warning you want, in my simple test case (see it live):
char func()
{
int x = 10 ;
return x ;
}
int main() {}
I receive the following warning:
warning: conversion to 'char' from 'int' may alter its value [-Wconversion]
This is a really bad idea: char
is a certain size on most embedded systems (usually 1 byte so it's actually an unsigned char
) and if you end up setting your int result = 256
somehow, it will overflow and return 0. Your error just turned into a success. Crashy crashy (hopefully). Worse, maybe kill someone with your embedded device.
I know you're trying to fix this but even just returning magic numbers is dangerous.
Instead, declare an enumeration type that is an error. It will give you type safety (to an extent) and automatically create the correct return size for your functions.
typedef enum status {
STATUS_OK = 0,
STATUS_ERR1,
STATUS_ERR2,
// ... etc ...
} status_t;
status_t processSomething (SomeType *something)
{
status_t result = STATUS_OK;
...
do stuff
...
return result;
}
This is much safer and the compiler will allocate only 1 byte for your returns until you have too many to fit, and only then will it make it bigger. Taken from the current C Standard (C99): http://www.open-std.org/JTC1/SC22/WG14/www/docs/n1256.pdf
6.7.2.2 Enumeration specifiers [...] Constraints The expression that defines the value of an enumeration constant shall be an integer constant expression that has a value representable as an int. [...] Each enumerated type shall be compatible with char, a signed integer type, or an unsigned integer type. The choice of type is implementation-defined, but shall be capable of representing the values of all the members of the enumeration.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With