기묘한 typedef의 활용

gmp (gnu multiprecision) 라이브러리를 쓸 일이 있어서 메뉴얼과 헤더파일을 보던 중 재밌는 코드를 발견!

typedef struct
{
  int _mp_alloc;        /* Number of *limbs* allocated and pointed
                   to by the _mp_d field.  */
  int _mp_size;         /* abs(_mp_size) is the number of limbs the
                   last field points to.  If _mp_size is
                   negative this is a negative number.  */
  mp_limb_t *_mp_d;     /* Pointer to the limbs.  */
} __mpz_struct;

typedef __mpz_struct mpz_t[1];

이 부분에 대해서 메뉴얼은 다음과 같이 설명하고 있다.

For interest, the GMP types mpz_t etc are implemented as one-element arrays of certain structures. This is why declaring a variable creates an object with the fields GMP needs, but then using it as a parameter passes a pointer to the object. Note that the actual fields in each mpz_t etc are for internal use only and should not be accessed directly by code that expects to be compatible with future GMP releases.

이 정의를 활용하는 코드를 보면 다음과 같다.

     void
     foo (mpz_t result, const mpz_t param, unsigned long n)
     {
       unsigned long  i;
       mpz_mul_ui (result, param, n);
       for (i = 1; i < n; i++)
         mpz_add_ui (result, result, i*7);
     }
    
     int
     main (void)
     {
       mpz_t  r, n;
       mpz_init (r);
       mpz_init_set_str (n, “123456”, 0);
       foo (r, n, 20L);
       gmp_printf (“%Zd\n”, r);
       return 0;
     }

이렇게 선언해 놓고 참조하면 자연스럽게 함수 호출할 때 call-by-reference가 가능하다. c언어의 묘미란 이런게 아닐까?

“기묘한 typedef의 활용”에 대한 6개의 생각

  1. 다음과 같은 활용도 가능할듯
    1..문자열형 만들기
    typedef char[] String; //typedef char* String; 도 가능할 듯
    //테스트 해보지 않아서 되는지는 모름
    2.클래스 포인터 없이 생성하고 사용하기
    typedef class Test
    {
    public:
    엠버들
    }Test;

    Test t = new T();
    //↑역시 테스트 해보지 않아서 어찌 될련지는..
    혹은..
    class Test
    {
    public:
    멤버들
    };

    typedef Test* test;
    이런식으로 해서
    test t = new test(); // 잘 될련지는..
    test t = new Test(); // 이것도 마찬가지.. 둘중 하나만 되거나 다 안되거나.. 할거 같음.

    1. 테스트 해보고 알려 주시면 좋았을 것을… ^^; 최근에는 function pointer type을 typedef로 놓고 사용하니 정말 편리하더라구요. 워낙 parameter가 많은 함수였거든요.

  2. 몇몇은 되는거 같더군요.. 다시 테스트해봐야지.. 그리고.. 근래에 C++빌더로 이벤트 만들어보는 연습하다가 알게 됬는데.. typedef가 함수 포인터까지 자료형화 해버리네요..
    즉 typedef void (*pFunc)();
    하면 나중에
    pFunc Func1, Func2;
    Func1 = Func; //Func() 함수가 있다고 가정
    Func2 = TestFunc; //이것역시 있다고 가정


    Func1();
    Func2();

    식의 기묘한 코드가 가능함..

  3. 위에 가능할것 같다고 한 소스를 직접 확인해봤는데 확인결과 아래 2가지만 에러없이 컴파일되고 실행되네요..
    1.문자열
    #include

    typedef char* String; //typedef char[] String; 하면 에러남
    void main()
    {
    String str = “테스트”;
    printf(“%s\n”,str);
    }

    2.포인터 없이 객체 생성, 사용하기
    – 클래스에 직접 적용
    #include

    typedef class Test
    {
    public:
    int a;
    }* test;

    void main()
    {
    test t = new Test(); //test t = new test(); 하면 에러남
    t->a = 5;

    printf(“%d\n”,t->a);
    delete t;
    }

    -별도로 지정
    #include

    class Test
    {
    public:
    int a;
    };

    typedef Test* test;
    void main()
    {
    test t = new Test(); //test t = new test(); 하면 에러남
    t->a = 5;

    printf(“%d\n”,t->a);
    delete t;
    }

댓글 남기기