Avatar33 Avatar33 - 2 months ago 5x
C++ Question

Shouldn't C++ compiler issue a warning for literal to negative number conversions

I made a very silly mistake in the following code:

int main(int argc, char *argv[])
const int ARR_SIZE = 2147483648;
int* intarr = (int *) malloc(sizeof(int) * ARR_SIZE);
for(int i =0; i < ARR_SIZE; i++) {
intarr[i] = i;

So I really should have used an unsigned int for ARR_SIZE. 2147483648 when assigned to a signed 32-bit int is really the largest negative number.
Is there a good reason why the compiler doesn't (or shouldn't) issue a warning for this. Should I require an explicit cast when assigning a positive literal that is larger than a types maximum value? (For the case where I really wanted a negative number)

(Source language was C++ when I ran into this but I think this is just as much a C question).

This was with g++ 6.1.1 and compiled as such:

g++ -Wall -g -o test_so test_so.cpp


Using the switch -Wconversion to gcc, you will get the following warning on ILP32, LP64, LLP64 platforms:

test.c:5:26: error: conversion to ‘int’ alters ‘long int’ constant value
    const int ARR_SIZE = 2147483648;

This warning flag is not included in either -Wall or -Wextra.

Also do note that an integer literal always has a type that is large enough to contain it, but at least int, on C. (On C++, a character literal will have type char instead!). In this case 2147483648 is of type long int, as on this platform long int has 64 bits (LP64); on Windows (LLP64) it would be a `long long int'.

Quoting the holy book (n1570),

The type of an integer constant is the first of the corresponding list in which its value can be represented

and for suffixless decimal literals, the list is int, long int, and long long int.