Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Hexadecimal constant in C is unsigned even though L suffix

I know this is a simple question but I'm confused. I have a fairly typical gcc warning that's usually easy to fix:
warning: comparison between signed and unsigned integer expressions

Whenever I have a hexadecimal constant with the most significant bit, like 0x80000000L, the compiler interprets it as unsigned. For example compiling this code with -Wextra will cause the warning (gcc 4.4x, 4.5x):

int main()
{
long test = 1;
long *p = &test;
if(*p != 0x80000000L) printf("test");
}

I've specifically suffixed the constant as long, so why is this happening?

like image 781
test Avatar asked Jul 18 '11 05:07

test


People also ask

Is hexadecimal signed or unsigned?

A hexadecimal value is int as long as the value fits into int and for larger values it is unsigned , then long , then unsigned long etc. See Section 6.4.

What is hexadecimal constant in C?

If an integer constant begins with 0x or 0X, it is hexadecimal. If it begins with the digit 0, it is octal. Otherwise, it is assumed to be decimal.

What is L in C hexadecimal?

L stands for long ; LL stands for long long type. The number does not need to be hex - it works on decimals and octals as well. 3LL // A decimal constant 3 of type long long 03L // An octal constant 3 of type long 0x3L // A hex constant 3 of type long.

What is unsigned integer constant in C?

Unsigned integer constant is an integer constant which has the permissible range from 0 to 65536. Thus significance of declaring a constant as unsigned almost doubles the size of the largest possible value.


2 Answers

The answer to Unsigned hexadecimal constant in C? is relevant. A hex constant with L suffix will have the first of the following types that can hold its value:

long
unsigned long
long long
unsigned long long

See the C99 draft, section [ 6.4.4.1 ], for details.

On your platform, long is probably 32 bits, so it is not large enough to hold the (positive) constant 0x80000000. So your constant has type unsigned long, which is the next type on the list and is sufficient to hold the value.

On a platform where long was 64 bits, your constant would have type long.

like image 94
Nemo Avatar answered Oct 08 '22 03:10

Nemo


Because your compiler uses 32-bit longs (and presumably 32-bit ints as well) and 0x80000000 wont fit in a 32-bit signed integer, so the compiler interprets it as unsigned. How to work around this depends on what you're trying to do.

like image 27
David X Avatar answered Oct 08 '22 03:10

David X