arithmetic overflow with enum

Discussion in 'C++' started by Fraser Ross, Oct 9, 2005.

  1. Fraser Ross

    Fraser Ross Guest

    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.
     
    Fraser Ross, Oct 9, 2005
    #1
    1. Advertising

  2. Fraser Ross

    Greg Guest

    Fraser Ross wrote:
    > 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
     
    Greg, Oct 9, 2005
    #2
    1. Advertising

  3. On Sun, 9 Oct 2005 15:18:45 +0100, "Fraser Ross" <> wrote:

    >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;
    }

    --
    Bob Hairgrove
     
    Bob Hairgrove, Oct 9, 2005
    #3
  4. Fraser Ross

    Fraser Ross Guest

    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.
     
    Fraser Ross, Oct 9, 2005
    #4
  5. Fraser Ross

    Ian Guest

    Fraser Ross wrote:
    > 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
     
    Ian, Oct 9, 2005
    #5
  6. Fraser Ross

    Fraser Ross Guest

    "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.
     
    Fraser Ross, Oct 10, 2005
    #6
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. dlamoris
    Replies:
    0
    Views:
    884
    dlamoris
    Oct 26, 2006
  2. joshc
    Replies:
    5
    Views:
    559
    Keith Thompson
    Mar 31, 2005
  3. darrel
    Replies:
    4
    Views:
    825
    darrel
    Jul 19, 2007
  4. rop rop

    Arithmetic overflow checking

    rop rop, Jul 6, 2011, in forum: Java
    Replies:
    233
    Views:
    3,526
    Wolfgang Draxinger
    Sep 8, 2011
  5. tm

    Re: Arithmetic overflow checking

    tm, Jul 10, 2011, in forum: C Programming
    Replies:
    88
    Views:
    1,942
    Wolfgang Draxinger
    Sep 8, 2011
Loading...

Share This Page