3

I ran into the following problem recently. Since it is somewhat tricky, I have posed it as question/answer pair for the people of the future.

According to these questions (Unsigned hexadecimal constant in C?, C interpretation of hexadecimal long integer literal "L") literals are fit into the first datatype that can represent them. In this case, the list should be:

int
unsigned int
long int
unsigned long int
long long int
unsigned long long int

This behavior comes from the C standard 6.4.4.1. However, if you write the following code (I used C++) with -Wsign-conversion enabled:

int32_t mask = 0xFF00FF00;

. . . then one obtains:

<file>:<line>:17: warning: conversion of unsigned constant value to negative integer [-Wsign-conversion]
  int32_t mask = 0xFF00FF00;
                 ^

I find this strange because 0xFF00FF00 is the binary representation of the integer -16,711,936, which easily fits in an int. What's the problem?

Community
  • 1
  • 1
geometrian
  • 14,775
  • 10
  • 56
  • 132

1 Answers1

6

The problem is that 0xFF00FF00 isn't viewed by the compiler as negative. It has no way of knowing that you mean for the highest bits to be sign bits.

Instead, the literal is viewed as the positive number 4,278,255,360, which doesn't fit into the integer's maximum value of 2,147,483,647. Hence, the compiler moves one step down the list, choosing the unsigned int, thus triggering the warning.

geometrian
  • 14,775
  • 10
  • 56
  • 132