2013-06-20 7 views
7

명백한 축소 변환을 발견 한 난처한 상황에 직면 해 있지만 컴파일러 (gcc-4.7.2)가 -Wall -Wnarrowing -pedantic 플래그에도 불구하고 경고를 발생시키지 않았다는 점에 실망합니다. 다음 프로그램을 참조하십시오 a1괄호로 초기화 할 때 좁힐 경고 없음

struct A { 
    int m; 
    A(int m) : m(m) {}; 
}; 

int main() { 
    unsigned long v = 0; 
    A a1(v); // narrowing, but no warning (should this not cause a warning?) 
    A a2{v}; // narrowing, warning raised (expected) 
} 

초기화 컴파일러에서 들여다로 너무 많이하지 않고 날 것으로 보인다. 내가 미쳐 버리지 않았는지 확인하기 위해 같은 방식으로 a1을 초기화하려고 시도했지만 괄호 대신 괄호를 사용했습니다. 컴파일러는 예상대로 두 번째 경우의 범위 지정에 대해 경고합니다.

분명히 밝히고 싶습니다. 초기화 목록에서 변환을 좁힐 수있는 적법성에 대해 묻지 않습니다. 나는 그것이 합법적이지 않다는 것을 안다 - a2의 중괄호로 묶은 초기화는 단순한 온 전성 체크였다. 제 질문은 초기화 목록과 관련이 없습니다. 이것은 중복 질문이 아닙니다.

컴파일러가 a1의 초기화를 좁히는 것에 대해 경고하지 않아야합니까?

+0

'a1'의 생성자는 암시 적 변환을 한 번 수행 할 수 있지만'a2'의 생성자는 할 수 없습니다. 왜 그들이 같아야한다고 생각하니? –

+1

'-Wconversion' 플래그를 추가하면 어떨까요? –

+0

이것은 중복되지 않습니다. 이미 초기화 목록 내의 변환을 축소하는 것이 불법임을 알고 있습니다. 나는 괄호로 initializer를 요구하고있다. –

답변

2

Wsign-conversion 코드 행에 대해 경고를 생성합니다 - -Wconversion하지 않습니다 unsigned longint는 (많은 플랫폼에 사실, 심지어 일부 64 비트 플랫폼) 크기가 동일 할 때. C 코드의 경우 -Wconversion은 암시 적으로 -Wsign-conversion을 활성화하지만 C++에서는 발생하지 않습니다.

long longv의 종류를 변경하는 경우, 그 자체로 -Wconversion 경고 (int 32 비트 인 것으로 가정)를 생성한다.

+0

통찰력을 가져 주셔서 대단히 감사합니다. 이니셜 라이저 목록 의미론이 변환에 대해 매우 구체적이기 때문에 기쁘다. - 이것은 내가 가장 휴대하기 쉬운 코드가 필요한 곳이면 어디에서나'{} '를 사용하여 시작할 수있는 좋은 이유 일 수있다. 그래서 컴파일러는 실제로 타겟으로하기 전에 변환 함정을 잡을 수있다. 새로운 플랫폼. –

관련 문제