자기 자신에 대한 함수포인터

theuhm의 이미지

그냥 스테이트 머신의 구현에 대해 생각해 보다가,
자기 자신에 대한 함수 포인터를 리턴하는 함수의 헤더는 어떻게 구성해야 하는가.. 라는 의문이 들더군요.
즉, 더 정확히 표현하자면, 자기 자신에 대한 함수 포인터를 리턴하는 함수의 리턴타입은 무엇이 되어야 하는가.. 가 되겠죠.
저는 아무리 궁리해 봐도 답이 안나오던데, 혹시 알고 계신분 있나요?
:shock:

lsj0713의 이미지

직접은 아무래도 무한순환이 되는지라 어렵고, 조금이나마 비슷하게 구현하자면 다음과 같은 방법이 있습니다.

#include <stdio.h>

struct tFP;

typedef struct tFP * (*FP)(int i, char c);

struct tFP * func1(int i, char c);

typedef struct tFP { FP p; } sFP;

sFP * func1(int i, char c)
{
    static sFP t;
    t.p = func1;
    printf("[%d,%c]", i, c);
    return &t;
}

int main(void)
{
    sFP fp1;
    fp1 = *func1(1, 'A');
    func1(2, 'B')->p(3, 'C');
    fp1.p(4, 'D');
    return 0;
}

pointer to incomplete type이 가능하다는 점을 악용한 방법입니다. 적법한 코드이니 이건 안심하고 쓰셔도 됩니다. :-)

표준문서를 아무리 뒤져봐도 자신에 대한 함수 포인터를 리턴하는 함수가 안된다고 직접 명시되어 있지는 않지만, 매개변수 타입이나 리턴값이 일치해야 한다는 여러가지 사항들을 생각해 볼 때 아무래도 불가능한 것 같습니다.

물론 경고메시지를 무시하고 이식성을 포기한다면 다음과 같은 코드가 gcc와 VC++에서 돌아가긴 합니다만... 저라면 정신건강상 포기하겠습니다. 포인터를 이용해서 함수를 호출하게 되면 int * 타입을 리턴하는 함수 포인터로 함수에 대한 포인터를 리턴하는 함수를 호출하는 꼴이 되기 때문에, 악영향을 미칠 가능성이 있습니다.

#include <stdio.h>

typedef int (*(*FP)(int i, char c))();

FP func1(int i, char c)
{
    printf("[%d,%c]", i, c);
    return func1;
}

int main(void)
{
    FP p;
    p = func1(1, 'C');
    p(1, 'C');
    return 0;
}
theuhm의 이미지

자기 자신에 대한 '함수포인터'를 리턴하는 함수는 선언 불가라는 거죠?

..

lsj0713의 이미지

네. 무엇보다 어떻게 선언부를 구성해야 하는지부터가 생각이 안나는군요. 자기 자신에 대한 '함수 포인터'를 리턴하려면 자기 자신이 무엇인지 알아야 하는데 그것은 자신이 어떤 타입을 리턴하는지를 알아야 알 수 있기 때문에... 무환순환논리에 걸립니다.

댓글 달기

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