简体   繁体   中英

narrowing conversion from int to long unsigned int {} is ill-formed in C++11

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 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.

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
};
  • you could change "value" to int
  • or you could use the new "enum class" (c++11) which is strongly typed, and declare your "value" as this type.

Since you're using c++11, you could declare your enum like so:
enum Enum2 : unsigned char;
That should force the enum to work. That said, IDEONE has no warnings/errors for your posted code. Could just be GCC being overly pedantic.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM