typedef에 관한 질문..

문석호의 이미지

typedef void (tmp)(ex);
라는 형식이 옳은 건가요?
소스를 보다 보니 이런 게 있던데..
머하는 건지 모르겠네요...
아시는 분 있음 답변 부탁드립니다.

맹고이의 이미지

위의 표현이 맞는진 잘모르겠구요

typedef void (*VoidFunctionPtr)(void *arg);

이런식이라면 함수포인터를 재정의(typedef) 하는겁니당..

앗.. 결국 제대로 아는것도 아닌데.. 괜히 리플을 단듯하네요;;;

pynoos의 이미지

가능합니다.

typedef 를 이해하는 방법은

http://bbs.kldp.org/viewtopic.php?p=15161#15161

에서도 썼지만,

typedef를 뗐을때는 변수선언이라고 생각하여 이해가 된다면, typedef 이해하기가 쉽습니다.

그 대상변수가 typedef의 대상이며 컴파일러가 그후로는 변수 table에 넣는 것이 아닌, type table에 넣어서 진행한다고 생각하시면 됩니다.

즉, typedef 는 일반 변수 선언문을 이용한 형 선언이지요.

typedef void (tmp)(ex); 

에서 tmp와 ex에 대한 형이 정확하다면 가능한 얘기겠지요.

익명 사용자의 이미지

pynoos wrote:
tmp와 ex에 대한 형이 정확하다면 가능한 얘기겠지요.

불가능합니다. ex는 사용자가 지정한 이름인데 형이 정확할 리가 없지요. 그런 형이 typedef 이전에 존재해서도 안되구요.
최종호의 이미지

gcc 3.0.3 에서 해 보니까 ex 를 그냥 파라메터 이름으로 인식해서
warning을 내긴 하지만 컴파일이 되는 것 같습니다.

% cat c.c
typedef void (tmp)(ex);
tmp a;
tmp b;
tmp c;

void a(int a, int b)
{
        printf("a = %d, b = %d\n");
}

void b(int a)
{
        printf("a = %d\n", a);
}

int c(int a, int b)
{
        printf("a = %d, b = %d\n");
}

main()
{
        a(1, 2);
        b(1);
        c(1, 2);
}

% gcc c.c
c.c:1: warning: parameter names (without types) in function declaration
c.c:17: conflicting types for `c'
c.c:4: previous declaration of `c'

% cc c.c
"c.c", line 1: warning: function prototype parameters must have types
"c.c", line 17: identifier redeclared: c
        current : function(int, int) returning int
        previous: function() returning void : "c.c", line 4
cc: acomp failed for c.c

cc는 cc: WorkShop Compilers 5.0 98/12/15 C 5.0
이고요.

결과로 봐서는 function type을 이름만 주면 parameter가 정해지지 않은 형태로 간주하는 것 같네요. 파라메터를 하나를 주건, 둘을 주건 별 상관 안하는 것과 cc의 warning 메시지를 봐서는요.

파라메터 받는 것이 서로 다른 함수들에 대한 템플릿(일반적인 의미의) 을 만들려고 저렇게 했을까요? 흠, 좋은 방식은 아닌 듯 생각됩니다. 해당 소스코드에서 어떻게 쓰였는지 보여주시면 재밌을텐데요. 그리고, 이건 함수에 대한 typedef 이므로 함수포인터에 대한 typedef 하고는 차이가 있습니다.
[/code]

pynoos의 이미지

컴파일도 안하고 설명하다가 헛점이...

typedef void (tmp)(ex);

에서 tmp나 ex 둘중하나는 typedef의 대상이 되는 것이죠.. ^^

ex가 대상이 되면 tmp가 먼저 정의 될 것이고,

tmp가 대상이 되면 ex가 먼저 정의 되어야 가능한 문법이 됩니당..

제가 보기엔 tmp가 대상(사용자가 지정하는 이름)이 되는 것 같습니다.

맹고이의 이미지

방준영 wrote:
불가능합니다. ex는 사용자가 지정한 이름인데 형이 정확할 리가 없지요. 그런 형이 typedef 이전에 존재해서도 안되구요.

typedef char ex;
typedef void (tmp)(ex);

이런식으론 안되는건가요..?
sunyzero의 이미지

typedef 시에 파라메터의 타입을 지정하지 않았으니 묵시적으로 int로 변환합니다.

그리고 선언시에 심볼만 선언되므로 타입에 대한 warning정도는 뜰 수 있지만, 아무 문제가 없는 코드입니다. 즉 밑에서 선언되는 녀석은 return 타입만 void로 맞춰주고, parameter는 무시해도 될것입니다.

따라서 ex는 int ex가 됩니다. 하지만, 선언만 하므로 코드에서 얼마든지 변경은 가능합니다.

========================================
* The truth will set you free.

익명 사용자의 이미지

실제로 함수 타입을 이렇게 정의해서 쓰는 사람은 전세계에 한명도 없을 겁니다. 왜냐 하면 tmp를 둘러 싸는 괄호는 불필요한 것이기 때문입니다. 질문하신 분이 함수 포인터 선언을 잘못 보고 올리신 것 같습니다.

그리고 컴파일이 된다고 코드가 정상적임을 의미하는 것은 아닙니다.

전웅의 이미지

pynoos wrote:
typedef void (tmp)(ex);

에서 tmp나 ex 둘중하나는 typedef의 대상이 되는 것이죠.. ^^

ex가 대상이 되면 tmp가 먼저 정의 될 것이고,

tmp가 대상이 되면 ex가 먼저 정의 되어야 가능한 문법이 됩니당..

tmp 가 먼저 정의되고 문제의 선언이 유효한 선언일 수는 없습니다. 일반적
인 명칭이 declaration-specifier 로 쓰일 수 있는 경우는 type-specifier
로 typedef-name 이 사용되는 경우 뿐인데, 이미 void 가 type-specifier
로 나와 있으므로 (tmp) 부터가 declarator 에 속합니다. declarator 의 문
법을 보면 무슨 수를 써도 실제 선언되는 명칭이 ex 가 되는 방법은 없습니
다. 따라서, 해당 선언은 tmp 가 매크로 명칭이 아닌 이상은 tmp 가 선언되
는 명칭에 해당하며, 결국 문제는 ex 가 typedef-name 인가로 넘어가게 됩
니다. 즉, tmp 를 둘러싸는 괄호는 명칭인 direct-declarator 를 둘러싸는
중복 괄호로 볼 수 있습니다.

sunyzero wrote:
typedef 시에 파라메터의 타입을 지정하지 않았으니 묵시적으로 int로 변환합니다.

그리고 선언시에 심볼만 선언되므로 타입에 대한 warning정도는 뜰 수 있지만, 아무 문제가 없는 코드입니다. 즉 밑에서 선언되는 녀석은 return 타입만 void로 맞춰주고, parameter는 무시해도 될것입니다.

따라서 ex는 int ex가 됩니다. 하지만, 선언만 하므로 코드에서 얼마든지 변경은 가능합니다.

근거 없는 이야기입니다. 다른 분이 이미 말씀해 주셨듯이 컴파일된다고
해서 올바른 프로그램인 것은 아닙니다.

방준영 wrote:
실제로 함수 타입을 이렇게 정의해서 쓰는 사람은 전세계에 한명도 없을 겁니다.

동의합니다 - 어차피 typedef 를 통해 선언된 함수형은 함수 정의에도 사용
될 수 없습니다. 하지만, 다른 데이터형을 유도하는 과정에서 가독성 증진
을 위해 사용될 "눈꼽" 만큼의 가능성은 있지 않을까 생각해 봅니다.

--
Jun, Woong (woong at gmail.com)
http://www.woong.org

kdaek의 이미지

보통은 아래와 같이 구조체를 만들때 쓰나
typedef struct{
int a;
char[] b;
}Test;

이러면 main() 에서
Test t;
t.a = 4;
...
이런식으로 사용하죠.. 간단히 말하면 자료형을 정의한다고 보면 됩니다.
위 같이 구조체뿐만 아니라 공용체(요새 안쓰는것중 하나)나 열겨형을 정의할때도 쓰지만.. 기묘하게
기존의 자료형을 재정의하는 기능도 있거든요.. 아래와 같이..
typedef int INTEGER;
...
INTEGER a;
a = 34;

이런식으로 실제로는 int인 INTEGER형이 생기는것이죠.. typedef를 이런식으로 상요하는 경우는 보통 포인터를 사용하기 쉽게하기 위함입니다. 일일이 쩜 찍는게 귀찮으니까.. typedef int* pint; (맞나?) 이런식으로정의하고 넣고 선언할때
pint a;
이런식으로 해버리죠..

그밖에 가장 기묘한것은 함수 포인터나 멤버함수포인터를 하나의 자료형으로 탈바꿈시키기도 합니다.
typedef void (*pFunc)(char *a);
하면 pFunc란 형이 void (*PFunc)(char *a);라는 함수 포인터를 나타내게 되어
pFunc pfunc1, pfunc2;
등으로 같은 함수포인터를 여러개 만들어 사용할 수 있게 됩니다.
이를 나중에 포인팅 및 사용할때
pfunc1 = Func1;
pfunc2 = Func2;
...
...
pfunc1("안녕하세요");
pfunc2("함수포인터입니다.");
...

이런식으로 사용이 가능하죠..
이상 재 짧은 지식입니다.

taeukim의 이미지

함수포인터로 쓰이는 형식이 맞습니다. 그럼!ㅋ

댓글 달기

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