Enumerations in C are signed or unsigned in GCC depending on whether
one of the values is negative. This prohibits forward-looking checks
that expect that enumerations may include a negative value in the
future.
For example, say we had silly color_t
enumeration:
typedef enum { RED = 0, GREEN = 1 } color_t; const char * string_of_color (color_t color) { static const char * colors[2] = { "RED", "GREEN" }; return colors[color]; } int main(void) { printf("Color: %s\n", string_of_color(0)); }
The output will be:
Color: RED
The program may crash if main was to call string_of_color(10)
. So we'll put in a check:
typedef enum { RED = 0, GREEN = 1 } color_t; const char * string_of_color (color_t color) { static const char * colors[2] = { "RED", "GREEN" }; if (color < 0 || color > 1) return "INVALID"; return colors[color]; } int main(void) { printf("Color: %s\n", string_of_color(0)); }
But now GCC complains:
warning: comparison of unsigned expression < 0 is always false
This breaks things because I might expect that we'd change the color enumeration to:
typedef enum { INVALID = -1, RED = 0, GREEN = 1 } color_t;
Now my check is valid and GCC doesn't complain. My workaround?
if ((int)color < 0 || color > 1) return "INVALID";
Another possible workaround is to add a negative value in color_t
or use a GCC compile-time option.
0 comments:
Post a Comment