전처리기 #define do{ 문장1; 문장2; 문장3 }while(0) 사용...
글쓴이: ktship77 / 작성시간: 수, 2005/04/13 - 12:52오전
리눅스 커널분석하다 보면..
#define XX do{ \ 문장1; \ 문장2; \ }while(0)
로 선언해 놓고,
코드 중에서
if( sss==1 ) XX; else .....
로 사용하는 경우가 많이 있습니다.
그런데.. 보니
#define XX 문장1, 문장2, 문장3
으로 해도 별 무리가 없어 보이거든요..
씨언어에 꽤 정통하신 분께 물어봐도 ... 대답은 가독성 때문이 아닐까... 라고 하던데.. 오히려 위의 것이 더 가독성이 없어 보이는데 여러분의 생각은요? 아님 아래의 것은 특정 제어문에서 동작되지 않는다든지.. 이렇건이 있는지 궁금합니다.
멋진 대답 부탁드립니다. :lol:
Forums:
http://bbs.kldp.org/viewtopic.php?t=1928
http://bbs.kldp.org/viewtopic.php?t=19289&highlight=while%280%29
유명한 질문이며 kldp에서도 여러번 보았던 질문 같군요.http
유명한 질문이며 kldp에서도 여러번 보았던 질문 같군요.
http://www.cinsk.org/cfaqs/html/node12.html#10.4
http://www.kernelnewbies.org/faq/#dowhile
만약 매크로 함수의 내용이 수식(expression)으로만 이루어졌다면 제안하신대로 (xxx, xxx, xxx) 와 같이 만드는 것이 나을 것입니다. 그러나 if, while과 같은 명령문(statement)이 들어가야 되는 경우에는 do while을 쓸 수밖에 없습니다.
[code:1]#define catch_exception(ce_a
또 다른 경우를 살펴보면 아래와 같습니다.
자그마한 도움이라도 얻으셨기를 ^^;
---------------------------------------
세계는 넓고, 할일은 많다.
Re: 전처리기 #define do{ 문장1; 문장2; 문장3 }while(0) 사용.
물론 if/while 등의 구조를 못 쓰는 것도 그렇고, 콤마를 사용할 경우 각각의 문장이 순서대로 실행된다는 보장도 없습니다. (예를 들어서 a += b;가 a = a + b;와 동치가 아니라던지 등등등...) 단지 대부분의 컴파일러는 위 문장을 순서대로 실행하도록 컴파일할 뿐입니다.
- 토끼군
한 마디로...전처리기는 문제가 없으나 인간이 실수를 하는것을 방지하
한 마디로...
전처리기는 문제가 없으나 인간이 실수를 하는것을 방지하기 위해 사용한다라고 보시면은 됩니다.
가독성이랑은 그렇게 관련이 없습니다.
<어떠한 역경에도 굴하지 않는 '하양 지훈'>
추신_인간의 실수는 인간의 지혜로 극복을 ...
#include <com.h> <C2H5OH.h> <woman.h>
do { if (com) hacking(); if (money) drinking(); if (women) loving(); } while (1);
Re: 전처리기 #define do{ 문장1; 문장2; 문장3 }while(0) 사용.
그렇지 않습니다. 쉼표 연산자의 중요한 특징은 sequence point로서 동작한다는
것입니다. 따라서 쉼표 연산자로 연결된 수식들은 항상 왼쪽 피연산자부터 평가됩니다.
물론 이것이 alwaysrainy님이 지적하신 문제를 해결해주는 것은 아닙니다.
전 아래와같이사용하는데..do while 를 왜쓰는지 모르겠군요..
전 아래와같이사용하는데..
do while 를 왜쓰는지 모르겠군요..
define A() \
{ a(); \
b(); }
또한 do while 를 사용한메크로는 함수내부에 인자로 사용될수도 없습니다. 그러나
제가하는방식은 함수내부에 인자로도 사용될수 있는장점이 있죠..
즉 printf( "%d", (A()) ); 등도 가능합니다.
----------------------------------------------------------------------------
[quote="alwaysrainy"]끝에 세미콜론 하나가 무척이나
님 진짜 친절하게 자세하게 설명하셨는데
틀렸습니다.
이렇게 되겠지요.
왜 do {} while 에서는 없던 괄호가 생깁니까?
개념없는 초딩들은 좋은 말로 할때 DC나 웃대가서 놀아라. 응?
[quote="ㅡ,.ㅡ;;"]전 아래와같이사용하는데..do while
가능하지 않습니다. 함수 인자로는 식(expression)만 쓸 수 있는데 { }로 둘러싸인
것은 식이 아니라 문장(statement)입니다. 문장을 ( )로 묶는 것은 문법 오류입니다.
[quote="girneter"][quote="alwaysrainy"]
그래도 do~while Statement 니까 한 문장처럼 넣을 수 있잖아요.
(앗, 그게 아니라 순수한 중괄호 이야기였나?)
Real programmers /* don't */ comment their code.
If it was hard to write, it should be /* hard to */ read.
[quote="doldori"][quote="ㅡ,.ㅡ;;"]전 아래와같이
잘되는데요..
그리고 설사 안된다해도 do while 보다 낫군요..
----------------------------------------------------------------------------
compound statement, 즉 중괄호로 싼 statement는
compound statement, 즉 중괄호로 싼 statement는 expression이 아닙니다. 따라서 함수의 인자로 쓸 수 없습니다. ISO C 표준 기준.
그러나, GCC의 확장 기능으로, compound statement를 expression으로 쓸 수 있습니다. 즉 함수의 인자로 쓸 수 있습니다. 현재까지 compound statement를 expression으로 완벽하게 지원하는 것은 gcc (C compiler)이며, g++ (C++ compiler)에서는 완벽하게 지원하지 않습니다. macro를 함수처럼 정의할 때 쓸모 있으며, obstack.h에서 제공하는 routine들이 대부분 이 방식을 써서 정의됩니다.
그러나, ISO C 표준에 따르면, 이 것은 문법 오류입니다. 다만 GCC의 확장 기능으로 expression으로 평가될 수 있다는 것을 알아 두셔야 합니다.
자세한 것은
해 보시면 알 수 있습니다.
C FAQ: http://www.eskimo.com/~scs/C-faq/top.html
Korean Ver: http://cinsk.github.io/cfaqs/
cinsk 님께서 언급하신 compound statement에 대해서는
cinsk 님께서 언급하신 compound statement에 대해서는 GCC 매뉴얼에 자세히 설명되어 있습니다. 이 페이지에서 예시 하나를 들면, 정수형으로 평가되는 a, b 중 큰 값을 side-effect 없이 반환하는 매크로는 다음과 같이 쓸 수 있습니다.
- 토끼군
덤: 개인적으로 GCC extension 중에서는 "a ? : b"를 좋아합니다... 뭐 사실 안 쓰지만. ;)
[quote="ㅡ,.ㅡ;;"][quote="doldori"][quote=
해보세요.
아마도 이렇게 될 것 같군요
dasomoli의 블로그(http://dasomoli.org)
dasomoli = DasomOLI = Dasom + DOLI = 다솜돌이
다솜 = 사랑하옴의 옛 고어.
Developer! ubuntu-ko! 다솜돌이 정석
위와같은경우는 {}만 있으면 잘못되는군요..그러나 위와같은경우도 토끼
위와같은경우는 {}만 있으면 잘못되는군요..
그러나 위와같은경우도 토끼군님이 예시하신방법이나
혹은 ( a(), b() ) 같이 하면됩니다.
매크로의 용도에따라 ({})처럼쓰기도 하고 {} 혹은 () 만으로
defile 하기도 하죠..
그러나 do while 은 그리 필요성을 못느끼겠더군요..
----------------------------------------------------------------------------
[quote]위와같은경우는 {}만 있으면 잘못되는군요..그러나 위
표준 신경 안쓰며 gcc 이외의 컴파일러는 사용하지 않는다면 말이죠.
[quote="돼지군"][quote="girneter"][quote="a
ㅇ ㅏ.. 실수가 있었네요.. ^^; 중괄호는 빠져야 겠네요
---------------------------------------
세계는 넓고, 할일은 많다.
[quote="amister"][quote]위와같은경우는 {}만 있으
상황에 따라 여러 매크로를 쓰거나 또 특정 컴파일러만 사용할 경우에 do while 은 오히려 거추장 스러울 수도 있겠네요.
하지만 do while가 모든 상황에서 가장 잘 적용된다는 사실은 분명하네요. 특히 코웍을 할 경우 사용자 실수를 예상하여야 한다면 상황에 따라 여러 방법을 쓸수 있는 것 보단 항상 적용되는 한가지 방법이 유리할 수 있죠.
(함수파라미터로 쓰이는 부분은 빼구요)
[quote="ㅡ,.ㅡ;;"]위와같은경우는 {}만 있으면 잘못되는군요..
댓글 좀 자세히 읽어 보시길 바랍니다.
kldp에 여러번 실렸던 내용입니다.
ㅡ,.ㅡ;; 님은 모든 매크로를 어떻게 define 했는가 일일이 확인하고, 모두 외우시나요?
댓글 달기