John Brooks
John Brooks

Reputation: 61

gcc warning for different return type

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

Upvotes: 6

Views: 1336

Answers (3)

Tak
Tak

Reputation: 1

Making the return type smaller than int on ARM or PowerPC will just increase the code size and execution time due to additional masking/extending instructions. Make the return type enum and let the compiler to optimize what is possible for given system.

Upvotes: 0

Shafik Yaghmour
Shafik Yaghmour

Reputation: 158469

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]

Upvotes: 7

rost0031
rost0031

Reputation: 1926

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.

Upvotes: 3

Related Questions