Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

gcc warning for different return type

Tags:

c

gcc

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

like image 767
John Brooks Avatar asked Jun 17 '15 20:06

John Brooks


People also ask

How do I enable warnings in GCC?

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.

How does GCC treat warning errors?

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.

Which option of GCC inhibit all warning messages?

If -Wfatal-errors is also specified, then -Wfatal-errors takes precedence over this option. Inhibit all warning messages. Make all warnings into errors.

Which option can be used to display compiler warnings?

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.


2 Answers

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]

like image 124
Shafik Yaghmour Avatar answered Sep 18 '22 10:09

Shafik Yaghmour


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.

like image 38
rost0031 Avatar answered Sep 19 '22 10:09

rost0031