arithmetic overflow with enum

F

Fraser Ross

void f(unsigned int const x) {
};
int main(int argc, char* argv[]){
//unsigned short a=0xFFFF;
enum { a=0xFFFF };
f(a*0x10000+0xFFFF);
return 0;
}

I get an arithmetic overflow when using a as an enum. I prefer
constants to be enum values so I have a problem with this.

Fraser.
 
G

Greg

Fraser said:
void f(unsigned int const x) {
};
int main(int argc, char* argv[]){
//unsigned short a=0xFFFF;
enum { a=0xFFFF };
f(a*0x10000+0xFFFF);
return 0;
}

I get an arithmetic overflow when using a as an enum. I prefer
constants to be enum values so I have a problem with this.

Fraser.

C++ tends to expect programs to use constants for constant values, and
enums for enumerated types (and for which the precise value of the enum
is immaterial).

Greg
 
B

Bob Hairgrove

void f(unsigned int const x) {
};
int main(int argc, char* argv[]){
//unsigned short a=0xFFFF;
enum { a=0xFFFF };
f(a*0x10000+0xFFFF);
return 0;
}

I get an arithmetic overflow when using a as an enum. I prefer
constants to be enum values so I have a problem with this.

Fraser.

Well, it overflows ... what else did you expect? You need to cast
either a or 0x10000 to a larger type than int to avoid the overflow.
Default integer promotion uses int instead, which is too small to
accommodate the resulting value.

Try this instead (if your platform supports UINT64 natively, you can
comment out the typedef or change it to "unsigned long long" instead
of __int64):

// test_enum.cpp
typedef unsigned __int64 UINT64;

void f(UINT64 const x) {
};
int main(int argc, char* argv[]){
//unsigned short a=0xFFFF;
enum { a=0xFFFF };
f(a*((UINT64)0x10000)+0xFFFF);
return 0;
}
 
F

Fraser Ross

Thats what I suspected was the problem. Its not necessary to cast to a
64 bit type though. unsigned int will do. In the documentation for
BCB6 in the description of 'treat enum types as ints' it says that "an
unsigned or signed short if the values of the enumeration are within the
following ranges: 0 to 4,294,967,295 or -2,147,483,648 to 2,147,483,647"
will be used for allocation. Is this a mistake with the ranges?

Fraser.
 
I

Ian

Fraser said:
Thats what I suspected was the problem. Its not necessary to cast to a
64 bit type though. unsigned int will do. In the documentation for
BCB6 in the description of 'treat enum types as ints' it says that "an
unsigned or signed short if the values of the enumeration are within the
following ranges: 0 to 4,294,967,295 or -2,147,483,648 to 2,147,483,647"
will be used for allocation. Is this a mistake with the ranges?
Please quote!

0xFFFF*0x1FFFF will overflow a 32 bit in no matter what. You have to
use a 64 bit int.

Enums are not intended for constants. Use a const int[8,16,32,64]_t
type instead.

Ian
 
F

Fraser Ross

"Ian"
0xFFFF*0x1FFFF will overflow a 32 bit in no matter what. You have to
use a 64 bit int.
That isn't the arithmetic expession. Multiplication is with a higher
priority than addition. The result is the maximum value of an unsigned
32bit integer.


Enums are not intended for constants. Use a const int[8,16,32,64]_t
type instead.


I disagree and would say they are better. They are lvalues whereas
integers are rvalues.

Fraser.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads


Members online

Forum statistics

Threads
473,755
Messages
2,569,535
Members
45,007
Latest member
obedient dusk

Latest Threads

Top