C언어에서 _stdcall 이라는 함수(?) 가 있나요?

yangam의 이미지

여기에 올려도 상관없는지 모르겠는데요.. ㅎ_ㅎ;;

제가 읽는책의 예제를 올려드릴께요

/*호출되는 쪽 */
int _stdcall myfunc(int a, int b)
{
return a + b;
}

/* 호출하는 쪽 */
int main()
{
int i;
i = myfunc(123, 456);
}

(아래는 _stdcall 의 역할에 대한 설명, 지루한 분은 맨아래의 질문으로..)
이건 제가 읽는 책에서 나온 예제이고, 아래는 설명입니다

_stdcall을 호출해서 프로그램의 크기를 작게 만드는 기법은
C언어로 프로그램을 만드는 경우에만 유효합니다...(중략)

스택은 프로그램의 여러 부분에서 반복해서 이용되는 메모리 영역입니다.
따라서 사용이 끝나면, 이처럼 원래 상태로 되돌리는 처리가 필요합니다.
이것이 바로 스택의 청소입니다. 참고로 C언어에서 함수의 리턴값은
스택이 아닌 레지스터를 통해 리턴하게 되어 있습니다.

이 스택의 청소 루틴을 호출된 함수에서 하면, 호출하는 함수에서 하는 것보다
전체 프로그램의 크기를 줄일 수 있는데, 이때 사용하는 것이 '_stdcall' 입니다.
좀더 자세히 설명하면, 함수 앞에 _stdcall을 두어 스택의 청소를 호출된
함수가 하도록 변경할 수 있다는 것입니다.

제가 원래 TC 2.0 or TC 3.0 을 쓰다가 처음으로 djgpp 라는 GUN용
C, C++ 컴파일러를 사용하고 있는데요...
여러 가지로 약간씩 다른 것 같더라구요.
main 의 타입을 int 로 하지 않으면 경고를 준다던지.. ㅎ_ㅎ?? (맞나요?)
(근데 이건 관습과도 같은건가요? 프로그램이 올바른 종료시 0을 돌려준다와
같은.. 무슨 프로그래밍시 GNU를 따르는 규약같은것도 있다고 들은 것
같은데.. ㅎ_ㅎ;;)

아래는 에러메세지 입니다...

_stdcall.c:3: error: parse error before "myfunc"

myfunc 앞에서의 문법적 에러라고 해석하면 되나요?

하지만 책에서는 분명히 int _stdcall myfunc(int a, int b) 라고
나와있는데 도데체 뭐가 문제인건지요..??

답변 주실 수 있는 분, 답변 부탁드립니다.. ㅎ_ㅎㆀ

cdpark의 이미지

Visual C++ 책을 보시는군요. :)

불리는 함수 쪽에서 stack을 정리하는 건 함수의 인자 수를 정확히 알 수 있을때만 쓸 수 있습니다.

codebank의 이미지

흑~ 잘못해서 설치활용 QnA로 갔었네요... :oops:

일단 내용이 프로그램에 관련된 질문이어서 게시물을 이동시켰습니다.

------------------------------
좋은 하루 되세요.

codebank의 이미지

보통 잘만들어진 책에는 앞부분에 이책의 내용은 어느 OS 어떠한 컴파일러에서
실험되었고 글이 쓰여졌다라는 말을 써놓습니다.
일단 책의 앞부분을보고 어디에 기준을 둔 책인지를 확인해보는것도 좋습니다.

int main (int argc, char* argv[])

가장많이보고 가장 많이 접하는 함수중에 하나죠.
문제는 main에서 리턴된는 값에 기인하는데 C언어의 표준이라는 POSIX에서는
반드시 main은 int형의 리턴값을 가지게하고 있습니다.
컴파일러마다의 차이점때문에 main이 int형을 가지지 않는것에 대해서 경고를 줄것인지
말것인지를 결정하는데 예전 Borland사(지금은 다른회사로 바뀌었죠.)에서 만들어진
컴파일러나 MS사에서 만들어진 컴파일러에서는 경고를 주진 않습니다.
물론 -W 옵션을 all같은걸로 만들면 POSIX규격에 맞춰서 경고를 출력하기도 합니다.
판매되는 컴파일러들의 표준 설정값은 보통 경고표시를 Middle정도로 두는것으로
알고 있습니다. 판매전략일 수도 있고 나름대로의 규칙을 가지고 있을 수도 있는데
각 회사마다 컴파일러를 판매할때 같이주는 책을 참조하면 POSIX규격은 거의
따르고 있습니다만 이규격은 설정을 바꾸어줌으로써 따르게 할 수도 그렇지 않고
좀더 유연하게 할 수도 있습니다.
GNU-C는 아마 초기 설정(옵션을 주지 않았을때)이 POSIX지원으로 되어있어서
(즉, -w옵션이 all로 되어있어서...) 그러한 경고를 주는것으로 알고 있습니다.

두번째 문제는 각 컴파일러의 특성때문에 일어나는 일로 알고 있습니다.
A사에서 만든 컴파일러에서는 errno를 _errno로 지정을 해놓고 B사에서는 __errno로
해놓으면 결국은 그러한 변수는 없다는 에러가 발생할 것입니다.
이 문제는 변수지정뿐만아니라 헤더파일 정의에도 문제의 소지가 있는데
보통 MS사나 Borland사에서 만들어진 컴파일러에서는 getc() 함수를 stdio.h
나 conio.h에 넣어 놓기도 하는데 GNU-C에서는 ctype.h에 넣어놓기도 합니다.
이러한 이유는 POSIX와 관련이 있기도 하면서 관련이 없기도하는데 POSIX에서
이러이러한 함수는 이러한 헤더파일에 꼭 넣어야한다는 규정이 없기 때문이라고
알고 있습니다. 또한 범용 변수도 기본적인 몇가지를 제외하고는 각 컴파일러 회사
자체적으로 넣을 수 있기때문에 (POSIX에 규격화 되지 않은 변수) 그러한 문제아닌
문제가 발생할 수도 있습니다.

결국 그러한 이유때문에 파싱에러가 발생할 수도 있는겁니다.

_stdcall에 대한것을 찾아보니 GNU-C에서는 정의된것이 없는것으로 나오는군요.

http://sources.redhat.com/ml/pthreads-win32/1999/msg00062.html

위 게시물을 보시면 알겠지만 mingw/msvcrt patch로 되어있는데 만일 STDCALL이
정의되어있으면 _stdcall을 포함시키고 정의되어있지 않으면 아무값도 찍지 않게
만드는 것을 볼 수 있을겁니다.
(mingw또한 GNU-C를 사용합니다.)

앞으로 프로그램 공부를 하면서 에러가 발생하는 부분이 있다면 일단은 그 컴파일러의
도움말에서 해당되는 함수나 변수가 있는지를 먼저 찾아보시는게 좋습니다.
특히 함수의 경우에는 컴파일러 회사에서 임의로 만들어서 넣어 놓는것이 종종
있으므로 꼭 한번씩 찾아보는것이 좋습니다. 이렇게하면 필요한 헤더파일도 찾을
수 있으니까요. :-)

------------------------------
좋은 하루 되세요.

방준영의 이미지

codebank wrote:
보통 MS사나 Borland사에서 만들어진 컴파일러에서는 getc() 함수를 stdio.h
나 conio.h에 넣어 놓기도 하는데 GNU-C에서는 ctype.h에 넣어놓기도 합니다.
이러한 이유는 POSIX와 관련이 있기도 하면서 관련이 없기도하는데 POSIX에서
이러이러한 함수는 이러한 헤더파일에 꼭 넣어야한다는 규정이 없기 때문이라고
알고 있습니다.

POSIX가 정의하는 것 중의 하나가 어느 함수가 어느 헤더에 들어가느냐는 것입니다. 들어 있는 헤더가 컴파일러마다 다른 함수들은 전부 비표준 함수라고 생각하시면 됩니다(아니면 뭔가 불가피한 이유가 있거나).
winner의 이미지

예전에 저도 읽은 적이 있었는데 그부분을 보고 저도 많이 의아해했죠.
이것이 과연 표준에 의해 보장이 될지 의심되더군요.

제 생각에는 그 수법은 사용하지 않는 것이 좋을 듯 싶습니다.

compiler 에는 최적화 option 이 속도뿐 아니라 code 크기에 대해서도 있으므로 그 정도로 충분하다고 생각되네요.

제가 생각하기에 이 책은 교양서적정도였습니다.
이 책은 무엇보다도 style 의 승리라고 생각합니다.

내용도 어느정도 흥미로운 부분을 다루기도 했습니다.
특히 data compression 에서 Huffman 이진트리를 사용하는 것은 흥미로웠죠.

실은 이해안하고 있다가 이산수학 수업들을 때 이해했죠...
(어처구니 없게도 시험문제 풀면서 적당히 했던게 정확했다... -_- 여기저기서 읽었던게 잠재의식에 영감을 준 모양...)

gurugio의 이미지

콜링 컨벤션을 지정하는거 아닌가요?

VC++에서는 standard call 이 됩니다.

윈도우즈 함수들은 대부분이 stdcall 이구요

ansi-c 함수들은 ccall 이라고 알고 있습니다.

음.. 콜링 컨벤션에 대한 자세한 내용은

어셈러브에 오시면 강좌에 적어놨습니다만...

그런데 답글다신 분들께서 다른 이야기를 하시는것 같은데요..

그렇다면 제가 잘못 알고있는 것일 수도 있습니다.

어쨌든 stdcall 은 리눅스에서는 안됩니다.

윈도우즈가 사용하는 콜링 컨벤션입니다.

리눅스는 모두 c call을 사용하니까요.

fast calling convention이라는 것도 있고 몇가지 종류가 있는 걸로

알고있습니다.

그 책은 읽어보지 않아서 정확히 뭘 말씀드려야 할지는 모르겠습니다만

일단 어셈러브에 있는 글 링크를 적겠습니다.

이걸 원하시는게 아니라면 낭패인데요... oops

http//www.asmlove.co.kr/zb41/zboard.php?id=study_free&page=3&sn1=&divpage=1&sn=off&ss=on&sc=on&select_arrange=headnum&desc=asc&no=22

fliers의 이미지

kihongss의 이미지

gurugio 님 빼고는 다른 얘기만 하시네요.
데브피아 가셔서 검색하심 많은 정보를 얻어실수 있습니다.

댓글 달기

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
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.