3

I have declared this enum in my header file:

enum wildcard {
  ....
  ....
  NW_SRC  = 0x111UL << 40,
  ....
};

When I compile it I get the following warning:

warning: left shift count >= width of type [enabled by default]

I think this is because enum type is treated as an int by the compiler. How to I resolve this?

Bruce
  • 33,927
  • 76
  • 174
  • 262

3 Answers3

3

The UL on your platform is probably 32 bit. You may need to use ULL instead:

enum wildcard {
    ....
    ....
    NW_SRC  = 0x111ULL << 40,
    ....
};

This will fix the warning, but the result of the expression may not necessarily fit in an enum (see this answer for details and references to the relevant standard documents).

Community
  • 1
  • 1
Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
3

You have two different problems, first the operation and then the declaration of the constant.

For the operation you could use the macro that is provided in inttypes.h

UINT64_C(0x111) << 40

to have a constant of the appropriate width.

But enumeration constants are int by definition of the standard, so this will not help you to define you an enumeration constant that is large enough to hold the value if on your platform int is only 32 bit wide (which is very likely).

Jens Gustedt
  • 76,821
  • 6
  • 102
  • 177
  • 1
    In C++ an enum is represented by an integral type large enough to hold all the enumerated values, meaning that it should be represented by long long in this case. Does the C standard really not make the same guarantee? – Jack Aidley Jan 17 '13 at 16:52
  • 4
    @JackAidley: C 2011 6.7.2.2 2: “The expression that defines the value of an enumeration constant shall be an integer constant expression that has a value representable as an int.” C 2011 6.7.2.2 3: “The identifiers in an enumerator list are declared as constants that have type int…” – Eric Postpischil Jan 17 '13 at 16:53
  • @Eric: thank you. Funny how these little differences in C and C++ can catch you out. – Jack Aidley Jan 17 '13 at 16:56
  • @JackAidley, yes this is actually a nasty difference, since this is concerning type constants and interface definitions. – Jens Gustedt Jan 17 '13 at 17:29
2

UL is unsigned long, but long on the majority of compilers is 32-bit. You want ULL for unsigned long long.

But as correctly pointed out by Jens Gustedt in their answer, in C an enum cannot hold values larger than an int anyway so this will not help. C++, in contrast, does allow enums to be represented by larger integral types.

Jack Aidley
  • 19,439
  • 7
  • 43
  • 70