C 매크로 함수의 return값 지정을 어떻게 하나요?
글쓴이: ixevexi / 작성시간: 목, 2005/10/13 - 5:16오후
보통
#define MAX(a,b) ( (a>b) ? (a) : (b) )
이런식으로 매크로 함수를 정의합니다.
하지만 약간 복잡한 형태의 함수의 return값을 명시적으로 주고자 했을때 어떻게 해야합니까?
즉
#define func(a) {\ //bla~ bla~ bla; \ /*return*/ result; }
이렇게 하게되면 {}로 둘러쌓인 부분이 result로 평가 받게 되나요?
혹은 그렇지 않다면 어떻게 해야합니까?
Forums:
조금 복잡하다면 함수로 만드는 게 옳은 방법이겠지요. :-)오버헤드가
조금 복잡하다면 함수로 만드는 게 옳은 방법이겠지요. :-)
오버헤드가 염려된다면 함수에다 __inline지시자를 주는 방법이 있겠습니다. 단, __inline은 컴파일러에게는 권고사항일 뿐이고, 반드시 지켜지는 것은 아닙니다.
----
Let's shut up and code.
inline으로 변화가 없어서 할려는 것이고게다가 조금복잡한게 아니라
inline으로 변화가 없어서 할려는 것이고
게다가 조금복잡한게 아니라 단순히 return값만 불리는 거라서 그렇습니다
C++, 그리고 C++....
죽어도 C++
[code:1]#define func(a) (
요런식으로 하면 result가 ({ blahblah...; result; }) 표현의 평가값이 되니까
식으로 사용할 수는 있을 것 같습니다만, 아무래도 이건 좀...-.-a
$PWD `date`
제가 궁금하던것이 바로 그것입니다.과연 { ~~~~~; ~~~~; r
제가 궁금하던것이 바로 그것입니다.
과연 { ~~~~~; ~~~~; result;}의 평가값이 result가 되는냐는 것이죠
문법적으로 옳은것인가요?
C++, 그리고 C++....
죽어도 C++
http://gcc.gnu.org/onlinedocs/gcc/Statem
http://gcc.gnu.org/onlinedocs/gcc/Statement-Exprs.html
GCC extension이라는 걸로 봐서 표준은 아닌 듯 합니다. -pedantic 옵션으로 컴파일 하니까 뭐라뭐라 그러네요. 하지만 다음과 같이 정의하는 건 표준 C 문법에 부합합니다.
즉, 선언'문' 없이, '식'으로만 이뤄져 있으면 GCC뿐 아니라 모든 ANSI C 컴파일러에서 문제가 없게 됩니다... 만, 원하시는 것에는 이프로 부족하지 않을까 싶네요-
$PWD `date`
매크로는 확장(expansion)될 뿐 그 이상도 이하도 아닙니다.소
매크로는 확장(expansion)될 뿐 그 이상도 이하도 아닙니다.
소스에 그대로 대치되는 것입니다.
실제로 전처리기가 매크로를 다 풀어헤친(?) 상태의 소스를 컴파일하게 됩니다.
매크로의 리턴 값이라고 하면 말이 앞뒤가 안맞는 느낌이 드네요.
-----
오늘 나의 취미는 끝없는, 끝없는 인내다. 1973 法頂
[quote="M.W.Park"]매크로는 확장(expansion)될 뿐
동의합니다. 8)
매크로에서의 리턴값이란거부터가 이미 말이 안되는거죠.
스스로 pre-processor입장이 되어서 매크로가 삽입되는 과정을
시뮬레이션 해보시면 잘 이해할 수 있을겁니다.
그럼 매크로에서 return 문을 쓰게 되었을 때 매크로가 값을
리턴하는게 아니라 매크로가 삽입된 함수가 값을 리턴하며
끝나게 된다는것도 이해가 가실줄로 압니다.
[quote="ixevexi"]제가 궁금하던것이 바로 그것입니다.과연
statement가 세개니까 각각 독립적으로 세번 평가 되겠네요.
그렇겠죠?
몇가지 정리하면 다음과 같습니다.첫째, 표준에 따라, statem
몇가지 정리하면 다음과 같습니다.
첫째, 표준에 따라, statement를 expression이라고 할 수 없습니다. 물론 statement의 정의에 따라, expression-statement가 될 수 있기는 하지만, 모든 statement가 expression이라고 할 수 없습니다. 따라서
는, 표준에 따라 잘못된 질문입니다.
둘째, 복잡한? 매크로를 만들고 싶다면 inline function을 쓰기 바랍니다. inline function을 쓰는 것이 여러모로 편리하고, 안전합니다. 다음과 같이 쓰면 좋습니다:
세째, gcc C 언어 확장 기능으로, (즉, 표준이 아니며, 다른 컴파일러에서 지원하지 않는..) compound statement (중괄호로 둘러싼 여러 statement)를 expression으로 해석하는 기능이 있습니다. 예를 들면:
로 쓴 것처럼, foo() 리턴 값의 절대값을 얻는 코드를 위와 같이 작성할 수 있습니다. 이 것은 C99 표준에서 inline function이 나오기 전에 매우 유용하게 썼던 기능입니다. expression에서 switch, for 등의 statement를 쓸 수 있는 등의 장점을 얻을 수 있었습니다. 실제로 GNU C library에 포함되어 있는 obstack에 관계된 대부분의 함수가 이 compound-statement expression을 써서 macro로 구현되어 있습니다. 물론 맨 마지막 statement의 값이, 이 compound statement의 값이 됩니다.
그런데, 이 기능은 현재 C++에서 쓸 경우, 임시 변수의 destructor가 불리는 순서가 바뀌는 등의 단점이 있기 때문에, C++로 쓸 우려가 있는 코드에서는 이 compound statement expression을 쓰지 말라고 권하고 있습니다.
개인적으로 간단한 수식으로 나올 수 있는 것이 아니라면 do { ... } while (0)을 써서 macro로 만들고, 어떤 값을 리턴할 필요가 있는 macro라면 inline function을 쓰는 것이 좋다고 생각합니다.
C FAQ: http://www.eskimo.com/~scs/C-faq/top.html
Korean Ver: http://cinsk.github.io/cfaqs/
매크로 함수 기능은 대단히 주의깊게 이용되어야만 합니다.http:
매크로 함수 기능은 대단히 주의깊게 이용되어야만 합니다.
http://groups.google.co.kr/group/comp.os.linux/browse_frm/thread/9690464b197bcb79
#define toupper(c) (_ctmp=c,islower(_ctmp)?_ctmp-('a'-'A'):_ctmp)
아무 문제 없을것 같은 코드지만
-------------------bug.c-------------------------
#include <linux/ctype.h>
main()
{
printf("%d\n", toupper('x') == toupper('y'));
printf("%d\n", toupper('x') == toupper('X'));
}
-------------------------------------------------
he program below prints:
1
1
but should print:
0
1
[quote="M.W.Park"]매크로는 확장(expansion)될 뿐
제가 쓴 글을 잘 읽어보세요 ^^ 오해하신것 같습니다.
매크로 함수의 return값은 말이 안되는것이 맞습니다만
a = func(); 와 같은 효과를 내기위해 물어본 것이었습니다.
저도 매크로 함수의 return값이 이상하다는 건 잘 알고 있습니다.
결론적으로 gcc extension을 사용하는 방법 이외에는 없네요
(gcc가 inline을 강제 하게 할 수 있는 방법을 찾지 않는이상)
원래 저도 표준의 inline을 썼다가 별 차이를 못느껴서
(inline이 적용이 되었나 안되었나를 모르겠더라구요^^)
macro함수를 쓰려던 것이었습니다.
저는 C++를 좋아하고 그렇기에 C스타일인 매크로 쓰는걸
별로 내켜하지 않습니다 ㅠ.ㅠ
C++, 그리고 C++....
죽어도 C++
매크로와 함수는 각각 할 일이 있는 거라고 봅니다. 함수 호출의 오버헤드
매크로와 함수는 각각 할 일이 있는 거라고 봅니다. 함수 호출의 오버헤드가 아주 중요한 요인으로 작용하는 경우가 아니라면, 함수를 쓰는 것이 맞다고 생각하구요. (그리고 그런 경우는 별로 없더군요..)
말씀하신 상황에서 굳이 매크로를 쓰고 싶으시다면 SOME_MACRO(input, output) 처럼 매크로를 정의해서 argument 에 바로 값을 넣도록 만드는 것이 옳은 방법이라고 생각합니다.
----
Let's shut up and code.
댓글 달기