GCC의 -wconversion 경고를 다루는 방법은 무엇입니까?
-
10-07-2019 - |
문제
GCC의 -wconversion 경고 플래그로 프로젝트를 구축하고 있습니다. 64 비트 GNU/Linux OS/하드웨어에서 (GCC (Debian 4.3.2-1.1) 4.3.2). 나는 어떤 유형을 사용해야하는지에 대한 혼합 된 유형 또는 명확성을 잃어버린 위치를 식별하는 것이 유용하다고 생각합니다.
경고를 활성화하는 대부분의 다른 상황에서는 그다지 도움이되지 않으며 다음을 어떻게 처리 해야하는지 묻습니다.
enum { A = 45, B, C }; /* fine */
char a = A; /* huh? seems to not warn about A being int. */
char b = a + 1; /* warning converting from int to char */
char c = B - 2; /* huh? ignores this *blatant* int too.*/
char d = (a > b ? b : c) /* warning converting from int to char */
위의 테스트의 예상치 못한 결과로 인해 (사례 a
그리고 c
) 또한 이러한 차이점을 설명 할 수 있습니다.
편집 : 그리고이 모든 것을 (char)
경고를 방지하기 위해?
edit2 : 일부 추가 사례 (위의 경우에 따라) :
a += A; /* warning converting from int to char */
a++; /* ok */
a += (char)1; /* warning converting from int to char */
그 외에도 제가 요구하는 것은 주관적이며 다른 사람들이 옹호하는 것을 고려할 때 다른 사람들이 전환 경고를 어떻게 처리하는지 듣고 싶습니다. 모두 경고.
Yae :
가능한 한 가지 해결책은 그냥 사용하는 것입니다 int
대신 char
맞아? 실제로, 더 많은 메모리가 필요할뿐만 아니라 다음 코드에서 시연 할 수 있듯이 느리게 진행됩니다. 수학 표현은 그와 함께 구축 될 때 경고를 얻기 위해 거기에 있습니다. -Wconversion
. 나는 버전을 사용한다고 가정했다 char
변수는 사용하는 것보다 느리게 실행됩니다 int
전환으로 인해 (64 비트 듀얼 코어 II) 시스템에서 int
버전은 느립니다.
#include <stdio.h>
#ifdef USE_INT
typedef int var;
#else
typedef char var;
#endif
int main()
{
var start = 10;
var end = 100;
var n = 5;
int b = 100000000;
while (b > 0) {
n = (start - 5) + (n - (n % 3 ? 1 : 3));
if (n >= end) {
n -= (end + 7);
n += start + 2;
}
b--;
}
return 0;
}
통과하다 -DUSE_INT
위의 스 니펫의 int 버전을 빌드하려면 GCC에.
해결책
당신이 말할 때 /* int */
그것이 당신에게 그것에 대해 경고를주고 있다는 뜻입니까? 이 코드에서 GCC 4.0.1 또는 4.2.1로 경고가 전혀 보이지 않습니다. -Wconversion
. 컴파일러는이 열거를 상수로 변환하고 있습니다. 컴파일 시간에 모든 것이 알려져 있기 때문에 경고를 생성 할 이유가 없습니다. 컴파일러는 모든 불확실성을 최적화 할 수 있습니다 (다음은 4.2.1의 Intel).
movb $45, -1(%rbp) # a = 45
movzbl -1(%rbp), %eax
incl %eax
movb %al, -2(%rbp) # b = 45 + 1
movb $44, -3(%rbp) # c = 44 (the math is done at compile time)
movzbl -1(%rbp), %eax
cmpb -2(%rbp), %al
jle L2
movzbl -2(%rbp), %eax
movb %al, -17(%rbp)
jmp L4
L2:
movzbl -3(%rbp), %eax
movb %al, -17(%rbp)
L4:
movzbl -17(%rbp), %eax
movb %al, -4(%rbp) # d = (a > b ? b : c)
이것은 최적화를 켜지 않습니다. 최적화를 사용하면 컴파일 시간에 B와 D를 계산하고 최종 값을 하드 코딩합니다 (실제로 필요한 경우). 요점은 GCC가 이미 가능한 모든 값이 char
.
편집 : 이것을 다소 수정하겠습니다. 할당에는 가능한 오류가 있습니다 b
, 그리고 컴파일러는 확실하지만 컴파일러는 결코 그것을 잡을 수 없습니다. 예를 들어, if b=a+250;
, 그러면 이것은 오버플로가 될 것입니다 b
그러나 GCC는 경고를 발행하지 않습니다. 과제가 있기 때문입니다 a
합법적입니다. a
a char
, 그리고 런타임에 수학이 오버플로되지 않도록하는 것은 (컴파일러가 아님) 문제입니다.
다른 팁
컴파일러는 이미 모든 값이 숯에 맞아 경고를 방해하지 않는다는 것을 이미 볼 수 있습니다. 나는 기대할 것이다 enum
편집 시작시 바로 해결됩니다.