가변인자 매크로 함수 질문

익명 사용자의 이미지


gcc에서 제공하는 가변인자 매크로 함수를 잘 쓰고 있는데요,,
이게 gcc가 안 깔려있는 플랫폼에 갔더니만 문제가 발생을 하네요.
Pro*C 같은 전처리기에서도 문제를 일으키고요.

혹시 가변인자 매크로 함수가 98년인가 99년에 제정된 C 표준에
정의되어 있는 내용인가요? 아니면 gcc만의 확장기능인가요?

그리고, 표준안에 대해서 나와있는 책이나 특별히 알아야 할 내용을
정리해 놓은 사이트 좀 추천해 주실래요?

고맙습니다,,

익명 사용자의 이미지

혹시 저의 답변이 다를수 있어서 그런데,
가변인자매크로함수가 va_list, va_start와 같은 variable argument
list access macros를
의미하는 가요? 한글용어엔 익숙치가 안아서요. -_-
variable argument list access list를 의미한다는 가정하에
아는 선까지만 답변드리겠습니다.

1. gcc 와 c99와의 관계

gcc는 현재 일명 C99 표준을 가장 먼저 지원한 컴파일러입니다.
(버전 몇부터 지원했는지 기억이 안나는 군요.-_-) 하기에 c99표준의 수
정 첨가된 내용을
가장 정확하게 지원하고있습니다.

C99 에서는 va_copy라는 메크로가 추가되었으며, variable argument
list access macros에 관한
내용은 stdarg.h에 정의되어 있습니다.

2. 표준안에 대해서 나와있는 책이나 특별히 알아야 할 내용을
정리해 놓은 사이트 좀 추천해 주실래요?

C99란 ISO에서 1999년도에 발표한 C 언어의 최신표준문법을 의미합니다.
99년도에 발표하였다고 해서 일명 C99라고 하며,
이 표준에 대하여 정확히 기술한 문서는 ISO에서 발행하고 있는
표준문서 입니다. 표준문서를 보시는 것이 가장 좋습니다.
구입방법은 ISO 홈페이지로 가셔서 돈주고 사시면 됩니다.
책으로된 표준문서보다 pdf 포멧으로된 문서가 훨씬 저렴합니다.

c99에 대한 표준을 다루고있는 책으로는 현재 제가 알기로는
C a reference malual (fifth edition)이라는 책이 있습니다.
저자는 Harbison 과 steele입니다.
단, 책의 내용이 c99표준의 모든 내용을 다루고 있지 않습니다.
하지만 c99를 알고싶어하는 입문자들에겐 훌륭한 리퍼런스입니다.

3. gcc 에서 제공하는 가변인자 매크로 함수라고 언급하셨는데,
정확히 어떤걸 이야기 하시는지 모르겠습니다.
그런걸 언급하셔야 답변하는 사람이 정확히 답변할수있을 것 같습니다.

4. 가변인자 매크로 함수가 98년인가 99년에 제정된 C 표준에
정의되어 있는 내용인가요? 아니면 gcc만의 확장기능인가요?

아니요. traditional C에서는 varargs.h를 통해 지원하였으며,
표준 C에서는 stdarg.h를 통해 지원하고있는 사항입니다.
단, varargs.h과 stdarg.h은 지원내용은 전혀 다릅니다.
하기에 표준C stdarg.h를 지원하는 코드를 작성하여야
만 이식성을 갖을 수 있습니다. 자세한 내용은
C a reference malual (fifth edition)를 보시면,
stdarg.h와 varargs.h를 비교하는 내용이 나옵니다.

익명 사용자의 이미지


안녕하세요?

저도 처음에는 variable argument macro function 이라고 써 놨다가
좀 너무 길어보이길래 한글로 바꿨었거든요..^^

말씀하신 stdarg.h나 vararg.h 에 있는 일반함수의 ... 파라메터 말고요,
gcc에서는 매크로 정의에서도 그런걸 할 수 있거든요.

그러니까 예를 들면,

#include < stdio.h >

#define printit(args, ...) printf(args, __FILE__, __LINE__)

main()
{
printit("Hello, world? (%s%d)\n");
}

같이 사용할 수 있습니다.
variable argument function과 비슷하지요?
보통 이전 방식으로 하면
#define printit2(x) printf x
printit2(("hello, world? (%s%d)\n", __FILE__, __LINE__));
방식으로 argument를 괄호로 가변인자 아규먼트를 모두 둘러싸는 식으로
처리했는데, 이런 경우 추가적으로 정보를 넣기가 곤란했거든요..
가변아규먼트처리는 가능한데, 보시는 것처럼 __FILE__, __LINE__ 을 직
접 써 주어야 했던 것 처럼여..

근데 이게 gcc 지원 안하는 다른 플랫폼에 갔더니만 전처리 에러를 내고,
Pro*C에서도 경고를 내더라고요.

다른 플랫폼에서는 매크로 풀어서 다시 다 작성했었고요,
Pro*C에서는 옵션으로 처리를 하기는 했지만, 매번 전처리시마다
경고가 나오니 영 깔끔해 보이지도 않고, 실제 경고를 놓치기도 해서여.

고맙습니다,,

익명 사용자의 이미지

표준 C 를 만들고 있는 위원회는 표준문서를 판매한 수익을 중심으로
재정운영을 하고 있습니다.

링크를 삭제하여 주시기 바랍니다.
공유도 좋지만, 이건 불법입니다. 이익을 내려고 파는 것도 아니고,
표준 C 를 관리하고있는 위원회의 운영자금을 충당하는데 소요되는 재정
원천입니다. 책으로된 표준문서는 비싸지만, 아크로벳 파일로 배포되고
있는 표준문서는 18달러 밖에 안합니다.

구입하셔서 보십시오,
그리고 링크 시키신 분은 삭제바랍니다.

익명 사용자의 이미지

- 삭제 -

관련글이 있다고 글자체는 삭제가 안되네요

thisnome의 이미지

위에서 논의 되었던 문제로 고생하고 있어, 기존 쓰레드를 다시 사용하여 질문 드립니다.
제가 gcc 컴파일러 환경에서 다음과 같이 매크로를 사용하고 있습니다.

#define Tracef(log_class, format, args ...)	log_writef(log_class, __FILE__, __FUNCTION__, __LINE__, format, args)

근데 프로젝트를 윈도우 환경으로 포팅해야 될 일이 있어서 win32 환경에서 컴파일을 하려 하니.. 위의 매크로 함수에서 에러가 나더군요..
다중 파라메터 부분이 문제가 되는것 같은데..

혹시 해결 방법이 있을까요?

voider의 이미지

gcc 의 가변인자 매크로는 참 편리하고 좋습니다 하지만 그것은 표준이 아니라
확장입니다

표준에 언급된게 아닙니다
그래서 포팅을 염두해 둔다면 다른 방법을 사용해야 합니다.

#ifdef 를 사용해서 gcc 이외의 컴파일러에서 다른 방법을 사용하게 하시던지
va_* 류의 방법을 생각해 보셔야 합니다

-- 아쉬운 하루 되세요 --

pynoos의 이미지

voider wrote:
gcc 의 가변인자 매크로는 참 편리하고 좋습니다 하지만 그것은 표준이 아니라
확장입니다

표준에 언급된게 아닙니다
그래서 포팅을 염두해 둔다면 다른 방법을 사용해야 합니다.

#ifdef 를 사용해서 gcc 이외의 컴파일러에서 다른 방법을 사용하게 하시던지
va_* 류의 방법을 생각해 보셔야 합니다

C99 표준입니다. 아직 vc 가 지원안하는 표준이지요.

voider의 이미지

c99 표준이라고요?
헉 왜 몰랐을까요....
예전에 표준 문서를 볼땐 없었던거 같았는데^^
에구~~~

-- 아쉬운 하루 되세요 --

pynoos의 이미지

어..엄...

제가 말한 것은 "..." 을 define 문에 쓸 수 있다는 것이 표준이라는 것이었는데...

http://www.comeaucomputing.com/techtalk/c99/#variadicmacros

참고하세요...

thisnome의 이미지

:) 분위기를 보아하니 VC에서는 불가능 한것 같군요..

log_writef 라는 함수명 자체를 Tracef 식으로 바꿔서 처리해야겠네요.. 헐~
:wink:

thyoo의 이미지

좀 성가시지만

#define Trace(_x_) printf _x_

int main()
{
    int a = 1;

    Trace(("e.g. %d\n", a));

    return 0;
 }

더 쉬운 방법은

#define Trace printf

int main()
{
    int a = 1;

    Trace("e.g. %d\n", a);

    return 0;
}

아래 방법은 NDEBUG 유무에 따른 조건 컴파일등에서 소스 부스레기가 남는 단점이 있습니다.

___________________________________
Less is More (Robert Browning)

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.