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!

February 3rd, 2014, 04:47 AM

laserlight

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.

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.

February 3rd, 2014, 05:45 AM

rainbringer

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.

February 3rd, 2014, 06:12 AM

laserlight

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.

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.

also doesn't produce the compiler warning and shows the correct output.

February 3rd, 2014, 10:02 AM

Paul McKenzie

Re: Minimal integer value rolled-up

Quote:

Originally Posted by rainbringer

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?