sysconf 및 O3의 최적화 및
글쓴이: namola / 작성시간: 수, 2007/05/16 - 6:22오후
#include <stdio.h> #include <sys/types.h> #include <errno.h> #include <unistd.h> #include <stdlib.h> #define INVAL_FLAG -1 int main() { int retval; errno = 0; retval = sysconf (INVAL_FLAG); if (retval != -1) { printf ("sysconf succeeded for invalid flag (%i), retval=%d errno=%d\n", INVAL_FLAG, retval, errno); abort (); } else if (errno != EINVAL) { printf ("sysconf correctly failed, but expected errno (%i) != actual (%i)\n", EINVAL, errno); abort (); } else printf ("using invalid name\n"); return 0 }
위의 코드를 다음과 같이 주고 컴파일을 하면 제대로 실행이 안됩니다.gcc -g -O3 -Wall -o sysconf sysconf.c
O3의 경우는 최적화 옵션인데 레벨 1, 2, 3에서 제대로 실행이 안됩니다.gcc -g -O0 -Wall -o sysconf sysconf.c
gcc -g -Wall -o sysconf sysconf.c
위의 경우에서만 양호하게 돌아 갑니다.
즉 "using invalid name" 으로 출력 합니다.
아무래도 gcc쪽 버그인거 같습니다.( 버전은 feisty fawn의 4.1.2 )
다른 분들의 생각은 어떠 하신지요?
Forums:
버그가 아닐 수도
버그가 아닐 수도 있습니다.
기억은 가물거립니다만, 실제 최적화하면 안되는 코드를 본적이 있었습니다..
그리고, 최적화 옵션 메뉴얼을 보면,, 원하는 의도와 다르게 동작할 수 있다는
설명도 있었던것 같네요..
------------------------------------------------------------
개인 메일 서버를 만들어 사용합시다..
언제부터 e-메일이 포털의 전유물이 된거지??
home
말씀 하신것 처럼
말씀 하신것 처럼 최적화 옵션의 메뉴얼을 보면 원하는 의도와 다르게 동작 할수 있다고 나옵니다.
하지만 "-O1" 옵션에서도 문제가 발생하는것은 개인적인 생각으로는 문제가 있다고 판단 됩니다.
혹시 최적화하면 안되는 코드를 알게 되시면 말씀해주세요^^
errno = 0; 다음 줄에
다음 줄에
정도 추가하면 괜찮아지네요.
... 머리 아픕니다. 상당히.
신기해서 한번
신기해서 한번 따라가 봤습니다...
-S 옵션으로 컴파일만 한 어셈블리어 코드를 보니 정말로 "using invalid name\n"이라는 문자열 자체가 사라져 있더군요. 이게 웬 일인가 싶어서 sysconf() 대신 다른 함수를 호출하도록 해보니... 어랏, 이번엔 사라지지가 않습니다.
알고보니 sysconf() 함수의 정체가 사실은 매크로라거나, 인라인 함수였다는 스토리가 아닐까 하는 생각에 (그럴 리가...;; ) unistd.h를 살펴보니...
응? const? 이건 뭘까 싶어서 gcc 매뉴얼을 살펴보니 "__const__"는 대략 호환성을 위해 const" 대신에 쓴 것인 듯 하고, 그 속성의 의미인 즉,...
아하~ 컴파일러에게 "이 함수는 전역변수에 접근하지 않아~"라고 알려주는 게 const 속성이로군요. 그렇다면 gcc에겐 죄가 없는 셈입니다. 전역변수인 errno는 0으로 설정된 후 (sysconf()를 포함해서) 아무도 접근하지 않는 게 되어 "
errno != EINVAL
"가 항상 참이 되고, 따라서 마지막의 else 이후는 생략이 가능하다고 판단한 것일 테니까요.그렇다면 glibc에서 sysconf()의 구현은 어떻게 되어 있을까요? glibc 소스의 ~glibc/sysdeps/sysv/linux/i386/sysconf.c에 있는 __sysconf()는 i386에만 한정된 처리를 담당하고 나머지는 linux_sysconf()를 다시 호출해서 처리합니다.
linux_sysconf()의 정체인 즉 ~glibc/sysdeps/sysv/linux/sysconf.c에 정의되어 있는 __sysconf()인데, 마찬가지로 리눅스에 관련된 처리만 하고서 나머지는 posix_sysconf()를 호출하여 처리합니다. ~glibc/sysdeps/posix/sysconf.c를 열어 보니...
__set_errno()는 ~glibc/include/errno.h에 다음과 같이 정의가 되어 있군요.
아니, 분명히 errno에 접근을 하고 있군요!!! 혹시나 해서 ~glibc/posix/unistd.h를 살펴봐도 마찬가지로 sysconf()의 선언에 "__attribute__ ((const))"가 있구요. 흠... 도대체 왜???
그런데 glibc의 ChangeLog.11 파일에 다음과 같은 내용이 있군요.
오호랏~ 2000년 어느 날에 Ulrich씨께서 집어넣으신 거로군요. (그 아래에는 iconv의 한글 인코딩과 관련한 내용도 보이는군요 :-)
... 하지만 왜???
비슷한 때에 glibc 메일링 리스트에 sysconf()의 반환값 해석 방법을 물어보는 스레드가 하나 있었는데, 거기에 Ulrich씨가 댓글을 달기도 했군요. 하지만 아쉽게도 원래의 문제와 관련된 내용은 아니로군요.
자, 일단 여기까지입니다. 과연 Ulrich씨는 왜 함수 선언에 "__attribute__ ((const))"를 추가한 걸까요?
----
$PWD `date`
$PWD `date`
친절한 설명
친절한 설명 감사드립니다.
위의 내용으로만 비추어 봤을때는 최적화 옵션에 상관없이 전역 변수에 접근하지 않는것으로 판단이
됩니다. 이미 해보셔서 아시겠지만 최적화 옵션을 주지 않으면 양호하게 실행이 됩니다.
-----------------------------
-------------------------------
이건 뭐 익명도 아니고...
-------------------------------
== warning 대부분 틀린 얘기입니다 warning ===
뜬금없이 무슨
뜬금없이 무슨 소리예요?
왜 툭하면 익명을 걸고넘어가는지..
댓글 달기