when I run the below code - I'm getting the warning "narrowing conversion from int to long unsigned int inside {} is ill-formed in C++11 [-Wnarrowing]. I'm using GNU 4.8 compiler.
typedef struct TableEntry
{
unsigned long value;
const char *label;
} TableEntry;
enum FunctionType
{
NORMAL = 0,
RANGE = 1
};
TableEntry functionTypes[] =
{
{NORMAL, "NORMAL"},
{RANGE, "RANGE"}
};
I don't understand why compiler is considering enum as an int?
Is this a bug in GCC 4.8? Is there any workaround?
Any help is appreciated.
If you make a narrowing conversion intentionally, make your intentions explicit by using a static cast. Otherwise, this error message almost always indicates you have a bug in your code. You can fix it by making sure the objects you initialize have types that are large enough to handle the inputs.
A narrowing conversion changes a value to a data type that might not be able to hold some of the possible values. For example, a fractional value is rounded when it is converted to an integral type, and a numeric type being converted to Boolean is reduced to either True or False .
Usually underlying type of unscoped enumerations is int ( it can be any integral type that can represent all values of enumerators).
However I do not see any narrowing conversion because type unsigned long can represent all values of type int.
EDIT: It seems I am wrong because I found an example in the Standard that contradicts my assumption
unsigned int ui1 = {-1}; // error: narrows
So unsigned int can not be initialized by using an initializer list that contains a negative number.
So to avoid the warning the enumeration could be written as
enum FunctionType : unsigned int // or unsigned long
{
NORMAL = 0,
RANGE = 1
};
If practical do:
enum FunctionType
{
NORMAL = 0,
RANGE = 1
};
typedef struct TableEntry
{
FunctionType value;
const char *label;
} TableEntry;
TableEntry functionTypes[] =
{
{NORMAL, "NORMAL"},
{RANGE, "RANGE"}
};
Otherwise, change the type in the struct to int
, or explicitly base the enumeration on the same type as in the struct.
Btw., I the think g++ warning is unfounded and wrong, since the original code is valid C++03. Correction: As I understand it now, the diagnostic is correct, and this is a breaking change in C++11. I just couldn't believe it.
About the naming convention: those all uppercase identifiers are good for Java programmers (who are used to that convention), but in C++ they increase the chances of inadvertent text substitution. There are also the aesthetic considerations. Much win in reserving all uppercase for macros.
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