Kirill V. Lyadvinsky
Kirill V. Lyadvinsky

Reputation: 99585

Is there a way to make `enum` type to be unsigned?

Is there a way to make enum type to be unsigned? The following code gives me a warning about signed/unsigned comparison.

enum EEE {
    X1 = 1
};

int main()
{
    size_t x = 2;
    EEE t = X1;
    if ( t < x ) std::cout << "ok" << std::endl;

    return 0;
}

I've tried to force compiler to use unsigned underlying type for enum with the following:

enum EEE {
    X1 = 1,
    XN = 18446744073709551615LL
    // I've tried XN = UINT_MAX (in Visual Studio). Same warning.
};

But that still gives the warning.


Changing constant to UINT_MAX makes it working in GNU C++ as should be according to the standard. Seems to be a bug in VS. Thanks to James for hint.

Upvotes: 11

Views: 8981

Answers (6)

Zur
Zur

Reputation: 11

Per C++ Enumeration Declarations on MSDN:

enum EEE : unsigned {
    X1 = 1 
}; 

Upvotes: 1

James McNellis
James McNellis

Reputation: 355079

You might try:

enum EEE {
    X1 = 1,
    XN = -1ULL
};

Without the U, the integer literal is signed.

(This of course assumes your implementation supports long long; I assume it does since the original question uses LL; otherwise, you can use UL for a long).

Upvotes: 8

Johannes Schaub - litb
Johannes Schaub - litb

Reputation: 507005

You could also overload the operators if you want to compare it

enum EEE {
    X1 = 1
};

bool operator<(EEE e, std::size_t u) {
  return (int)e < (int)u;
}

However you have to do that dance for any integer type on the right side. Otherwise if you do e < 2 it would be ambiguous: The compiler could use your operator< matching the left side exactly but needing a conversion on the right side, or its built-in operator, needing a promotion for the left side and matching the rigth side exactly.

So ultimately, i would put the following versions:

/* everything "shorter" than "int" uses either int or unsigned */
bool operator<(EEE e, int u) {
  return (int)e < (int)u;
}

bool operator<(EEE e, unsigned u) {
  return (unsigned int)e < (unsigned int)u;
}


bool operator<(EEE e, long u) {
  return (long)e < (long)u;
}

bool operator<(EEE e, unsigned long u) {
  return (unsigned long)e < (unsigned long)u;
}

/* long long if your compiler has it, too */

Not very nice :) But at least the user of your enumeration has easy going. However if you ultimately don't want to compare against ordinary int but against some meaningful value, i would do what some other guy proposed, and add another enumerator that has as value 2, and name it. That way, warnings will go away too.

Upvotes: 2

In silico
In silico

Reputation: 52159

Not in the current version of C++. C++0x will provide strongly typed enums.

For the time being, you can use if ( static_cast<size_t>(t) < x ) to remove the warning.

Upvotes: 2

Potatoswatter
Potatoswatter

Reputation: 137820

Why not

enum EEE {
    X1 = 1,
    x = 2 // pick more descriptive name, a'course
};

or

if ( size_t( t ) < x )

Upvotes: 0

mathmike
mathmike

Reputation: 1014

According to Are C++ enums signed or unsigned? your compiler gets to choose whether enum is signed or not, though there are some comments saying that in C++0x you will be able to specify that it is unsigned.

Upvotes: 1

Related Questions