2016-08-20 52 views
0

我做了下面的代碼非常愚蠢的錯誤:應該不是C++編譯器問題的字面來負數警告轉換

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; 
    } 
} 

所以,我真的應該用於ARR_SIZE一個unsigned int。 2147483648當分配給一個帶符號的32位int時確實是最大的負數。 編譯器沒有(或不應該)爲此發出警告是否有充分的理由。當分配大於類型最大值的肯定字面值時,是否需要進行顯式轉換? (對於我真的想要一個負數的情況)

(源語言是C++,當我碰到這個,但我認爲這同樣也是一個C問題)。

這與G ++ 6.1.1,並彙編成這樣:

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

int的大小主要取決於平臺。 –

+3

問題是缺少編譯器版本和編譯選項。 –

+0

關於「積極文字」:沒有「消極文字」。 –

回答

6

使用開關-Wconversiongcc,你會得到ILP32,LP64,LLP64平臺以下警告:

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

此警告標誌是而不是包含在-Wall-Wextra中。


也不要注意,文字的整數總是有一個類型,它是大到足以容納它,但至少int,對C.(在C++中,字面將有類型char而不是一個字符!)。在這種情況下,2147483648的類型爲long int,因爲在此平臺上long int有64位(LP64);在Windows(LLP64)上,它將是一個'long long int'。

引用聖書(n1570),

類型的整數常數的是先在其值可以被表示

和suffixless十進制文字對應的列表的,該列表是intlong intlong long int

+0

謝謝安迪。很好的答案。我注意到,當我使用文字0x10000000,而不是使用-Wconversion時不再發出此警告。這很有道理,因爲正如你所說,將負數表示爲十六進制文字常見。 – Avatar33

+1

@ Avatar33現在這是溢出,它被'-Wall'捕獲。你的意思可能是'0x80000000'。這被'-Wconversion'和'-Wsign-conversion'捕獲,因爲十六進制常量是無符號的。 –

+0

0x10000000(7尾隨零)不是溢出,但我的意思是不是0x80000000是的。 – Avatar33