리눅스 환경에서 C로 코딩을 할 때, gcc는 좋은 '벗'이 되어 줍니다.

gcc 컴파일 과정을 지켜보며 error도 잡고 warning도 잡지요.


물론, 아주 드물게 '결코 잡을 수 없는' warning도 있습니다.

('결코 잡을 수 없는' warning이 무엇인지는 차후에 다시 포스팅하겠습니다)

하지만, 기본적으로는 warning은 컴파일 중에 눈을 끊임없이 현혹시키기에 제거해야 마땅합니다.



gcc는 끊임없이 버전을 업데이트해가며 새로운 기능을 탑재하고 있습니다.

새로운 기능 대부분은 기능개선이나 개발자 편의증진을 위해 추가하지만,

간헐적으로 수많은 논쟁을 불러일으키는 기능도 있기 마련이지요.


gcc 4.3에 추가된 "-Wparentheses"는,

이상없던 코드에서 warning이 검출되게 하여 격렬한 논쟁을 불러일으켰습니다.

warning: suggest parentheses around assignment used as truth value [-Wparentheses]

            if (tmp = strtok(NULL, "_"))

이 warning은 if 문 안에 '='(등식)이 있으면,

assignment인지 "=="의 오타인지 헛갈릴 수 있으니 분명히 정리하라는 경고이죠.


그 동안은 조건식에서 변수에 대입함과 동시에 괄호없이 변수의 참/거짓 값을 사용할 수 있었는데요,

이제부터는 조건식 내에 대입(=)이 이뤄지면,

괄호를 하나 더 사용하여 정말 대입(=)이 맞는지 확인해야합니다.


 if (tmp = strtok(NULL, "_")) ...

위의 경우라면, 아래처럼 변경하면 되겠지요.

 if ((tmp = strtok(NULL, "_")))

혹은

 if ((tmp = strtok(NULL, "_")) != NULL)

위처럼 사용하면 됩니다.


-Wall 옵션이 아래 나열한 수많은 옵션을 자동으로 추가하기 때문에,

개발자가 직접 추가하지도 않은 parentheses 옵션의 경고 문구가 나타났던 겁니다.

          -Waddress  
          -Warray-bounds (only with -O2) 
          -Wc++11-compat 
          -Wchar-subscripts 
          -Wenum-compare (in C/ObjC; this is on by default in C++)
          -Wimplicit-int (C and Objective-C only)
          -Wimplicit-function-declaration (C and Objective-C only)
          -Wcomment 
          -Wformat  
          -Wmain (only for C/ObjC and unless -ffreestanding) 
          -Wmaybe-uninitialized
          -Wmissing-braces (only for C/ObjC)
          -Wnonnull 
          -Wopenmp-simd
          -Wparentheses 
          -Wpointer-sign 
          -Wreorder  
          -Wreturn-type 
          -Wsequence-point 
          -Wsign-compare (only in C++) 
          -Wstrict-aliasing 
          -Wstrict-overflow=1 
          -Wswitch 
          -Wtrigraphs 
          -Wuninitialized 
          -Wunknown-pragmas 
          -Wunused-function 
          -Wunused-label    
          -Wunused-value    
          -Wunused-variable 
          -Wvolatile-register-var

(가운데쯤에서 parentheses에 대한 항목이 보이네요.)


조건문 내의 조건식에서 뿐만 아니라 아래와 같은 중첩 조건문에서도 경고 메시지를 받을 수 있습니다.

            if (a)
              if (b)
                foo ();
            else
              bar ();

위와 같은 경우에 else는 어느 if 문인지 불확실하겠지요?

코드를 분명하게 이해하기 위해 괄호를 써서 범위를 지정해야 합니다.


오늘은 여기까지 하겠습니다.

그럼 좋은 하루 보내세요.

끝_



* References

https://issues.apache.org/jira/browse/STDCXX-791

http://stackoverflow.com/questions/5476759/compiler-warning-suggest-parentheses-around-assignment-used-as-truth-value

https://gcc.gnu.org/onlinedocs/gcc-4.9.2/gcc/Warning-Options.html


+ Recent posts