강좌 & 팁
글 수 2,412
2011.10.22 20:47:24 (*.138.143.120)
49438
gcc 의 경고옵션은 가능한 무시하기 않고 그 의미에 대한 문제를 해결하는 것이 좋다.
그럼 컴파일시 보여지는 메세지에 대한 옵션이 어떤 것이 있는지 몇가지 알아본다.
-Wall : 일반적으로 유익하다고 생각되는 경고 메세지를 모두 표시한다.
-W : -Wall 로는 표시되지 않는 몇몇 경고 메세지를 추가로 표시한다.
이 옵션은 gcc4 에서 -Wextra 로 이름이 변경되었다.
-Wformat=2 : printf 함수 등의 출력형식 지정 문자열이 문자열이 아닌 경우에 경고한다.
-W strict-aliasing=2 : C 언어 표준규격상 허용되지 않는 방법으로 메모리에 접근할 경우 경고한다.
-O2 옵션과 함께 사용한다.
strict-aliasing=2 라는 옵션에 대한 좀더 상세히 알아보자.
이 옵션은 중첩되는 두 메모리 영역을 서로 다른 자료형 A,B 로 읽고 쓰기를 할 경우에 경고하는 옵션이다.
이와같은 읽고 쓰기는 C 언어 표준규격에서 금지되어 있으므로 의도적으로 수행할 경우를 제외하면
가능한 한 피해야 한다.
예제를 한번 살펴보자.
1 #include <stdio.h>
2
3 int main(int argc, char **argv)
4 {
5 int ray;
6
7 ray = 0;
8 ((short *)&ray)[0] |=1;
9 ((short *)&ray)[1] |=1;
10
11
12 printf("%d\n", ray);
13
14 return 0;
15 }
ray 라는 변수를 short 형태로 형을 강제지정하면서 수행하는 코드이다.
실행결과는 어떻게 될까?
root@boggle70-desktop:test# arm-generic-linux-gnueabi-gcc gcc-option.c
root@boggle70-desktop:test#
[root@falinux ~]$ /mnt/nfs/a.out
65537
[root@falinux ~]$
예상한대로 결과는 맞게 나왔다.
이번에는 O2 옵션을 주고 최적화를 시켜서 수행해 보자.
root@boggle70-desktop:test# arm-generic-linux-gnueabi-gcc -O2 gcc-option.c
root@boggle70-desktop:test#
[root@falinux ~]$ /mnt/nfs/a.out
0
[root@falinux ~]$
수행결과가 0 이다? 왜 이런 결과가 나온것일까? 아무런 에러도 발생시키지 않고 컴파일이 되었는데?
컴파일시 -S 옵션을 붙이면 두개의 차이가 확연히 보이게 됩니다.
-S 컴파일시에는 .s 파일을 만들어주는데 두번의 컴파일후 발생하는 코드는 확연히 달라집니다.
최적화를 통해 사용되는 레지스터는 강제형전환에 의한 C 언어표준규격상 지원하는 않는 방법으로
메모리에 접근하기 때문에 명확히 알고 사용하지 않는 경우에는 구성에 따라 이런 문제를 발생시킬 수도 있습니다.
최적화를 수행하는 옵션에서는 이러한 문제를 확인하기 위해서 strict-aliasing=2 옵션을 함께 사용합니다.
root@boggle70-desktop:test# arm-generic-linux-gnueabi-gcc -O2 -Wstrict-aliasing=2 gcc-option.c
gcc-option.c: In function 'main':
gcc-option.c:8: warning: dereferencing type-punned pointer will break strict-aliasing rules
gcc-option.c:9: warning: dereferencing type-punned pointer will break strict-aliasing rules
이제 컴파일 수행중에 해당 문장에 문제가 생길수 있음을 확인할수 있습니다.
최적화를 이용한 컴파일시에는 경고하는 메세지들을 무시해서는 안됩니다.
참조및 출처 : Binary Hacks - O'REILLY