CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 7 of 7
  1. #1
    Join Date
    Feb 2014
    Posts
    3

    Question Minimal integer value rolled-up

    Please explain me a strange (to me) behavior of the following piece of code:

    #include <iostream>
    using namespace std;

    #define MIN_VAL -2147483648

    typedef enum E_TEST
    {
    zero_val = 0,
    one_val = 1
    } E_TEST;

    void main()
    {
    if (zero_val > MIN_VAL)
    cout << "Not a problem!" << endl;
    else
    cout << "It's a problem!" << endl;
    }

    So, as you can guess, "It's a problem" is printed. I'd like to understand why. According to MSDN, the limits of a signed int are -(2^32)/2 to (2^32)/2-1, e.g. -2147483648 to 2147483647. Enums are also 4-bytes types. So where is the problem? Why the result isn't "Not a problem!" ?

    Thanks!

  2. #2
    Join Date
    Jan 2006
    Location
    Singapore
    Posts
    6,765

    Re: Minimal integer value rolled-up

    Quote Originally Posted by rainbringer
    According to MSDN, the limits of a signed int are -(2^32)/2 to (2^32)/2-1, e.g. -2147483648 to 2147483647.
    Check for yourself, e.g., #include <climits> and print INT_MIN and INT_MAX.

    Quote Originally Posted by rainbringer
    Enums are also 4-bytes types.
    Not necessarily true.

    Did you compile with warnings turned on at a high level? If so, what were the warnings, if any?

    Also, note that void main should be int main.
    C + C++ Compiler: MinGW port of GCC
    Build + Version Control System: SCons + Bazaar

    Look up a C/C++ Reference and learn How To Ask Questions The Smart Way
    Kindly rate my posts if you found them useful

  3. #3
    Join Date
    Feb 2014
    Posts
    3

    Re: Minimal integer value rolled-up

    I've checked in <limits.h>. INT_MIN defined as -2147483647-1. Why? Why not -2147483648 ?
    Why if I define #define MIN_VAL -2147483648 and do cout << MIN_VAL, I get +2147483648 ?

    I compile with warning level 3 and I do not get any warning.

  4. #4
    Join Date
    Jan 2006
    Location
    Singapore
    Posts
    6,765

    Re: Minimal integer value rolled-up

    Quote Originally Posted by rainbringer
    I compile with warning level 3 and I do not get any warning.
    Hmm... I was expecting you to get a warning about an integer constant/literal being too large for int.

    Quote Originally Posted by rainbringer
    I've checked in <limits.h>. INT_MIN defined as -2147483647-1. Why? Why not -2147483648 ?
    Why if I define #define MIN_VAL -2147483648 and do cout << MIN_VAL, I get +2147483648 ?
    The thing is, in the expression -2147483648, the integer literal is 2147483648. The unary operator- is applied to negate its value. However, if the range of int is [-2147483648, 2147483647], then 2147483648 would be an invalid literal for int. Hence, the literal may have type long int, but the guaranteed range of long int has an upper bound of 2147483647 too. If you are compiling with respect to a version of the C++ standard prior to C++11, then long long int might not be available, hence your integer literal would simply be invalid.
    C + C++ Compiler: MinGW port of GCC
    Build + Version Control System: SCons + Bazaar

    Look up a C/C++ Reference and learn How To Ask Questions The Smart Way
    Kindly rate my posts if you found them useful

  5. #5
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    7,822

    Re: Minimal integer value rolled-up

    Code:
    	if (zero_val > MIN_VAL)
    When I compile this with MSVC I get the following warnings
    Code:
    test3.cpp(16) : warning C4146: unary minus operator applied to unsigned type, result still unsigned
    test3.cpp(16) : warning C4127: conditional expression is constant

    Changing the code to this
    Code:
    #include <iostream>
    using namespace std;
    
    const int MIN_VAL = (-2147483647 - 1);
    
    typedef enum E_TEST
    {
    	zero_val = 0,
    	one_val = 1
    } E_TEST;
    
    int main()
    {
    	if (zero_val > MIN_VAL)
    		cout << "Not a problem!" << endl;
    	else
    		cout << "It's a problem!" << endl;
    }
    removes the compiler warning and produces the expected answer.

    Where possible, it's better to use a const rather than a #define. Also, if you need to use specific constants that have already been pre-defined, it is better to use them as they have been defined in the correct format.

    This program
    Code:
    #include <climits>
    #include <iostream>
    using namespace std;
    
    typedef enum E_TEST
    {
    	zero_val = 0,
    	one_val = 1
    } E_TEST;
    
    int main()
    {
    	if (zero_val > INT_MIN)
    		cout << "Not a problem!" << endl;
    	else
    		cout << "It's a problem!" << endl;
    }
    also doesn't produce the compiler warning and shows the correct output.
    All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!

    C++23 Compiler: Microsoft VS2022 (17.6.5)

  6. #6
    Join Date
    Apr 1999
    Posts
    27,449

    Re: Minimal integer value rolled-up

    Quote Originally Posted by rainbringer View Post
    I've checked in <limits.h>.
    That is not the way to check if a certain constant or value is a specific value. You should actually write a program to output what the value is.

    The reason is that header files can have #ifdef's or other preprocessor symbols that may result in values that are contrary to what you're seeing. What if that value you're seeing is surrounded by an #ifdef that may be FALSE? Or that definition is only "on" when another constant is TRUE?

    Regards,

    Paul McKenzie

  7. #7
    Join Date
    Feb 2014
    Posts
    3

    Re: Minimal integer value rolled-up

    O.K., I got it.
    Thanks to all for your quick answers!

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured