gcc 버그인지 아니면 코드 문제인지....?

mtorange의 이미지

아래와 같이 y.cpp 라는 파일을 만들어 두고..

      1 #include <stdio.h>
      2 
      3 class foo
      4 {
      5 public:
      6   foo()
      7   {
      8     puts("foo()");
      9   }
     10   template <class T> T *create()
     11   {
     12     return new T;
     13   }
     14 };
     15 
     16 class bar
     17 {
     18 private:
     19   foo *m_foo;
     20 public:
     21   bar(foo *x) : m_foo(x)
     22   {
     23     puts("bar()");
     24   }
     25   template <class T> T *create()
     26   {
     27     return m_foo->create<T>();
     28   }
     29 };
     30 
     31 
     32 template <class T> T *zzz()
     33 {
     34   foo x;
     35   return x.create<T>(); //-- compile error
     36 }
     37 
     38 template <class T> int *yyy()
     39 {
     40   foo x;
     41   return foo.create<int>(); //-- compile error
     42 }
     43 
     44 int *xxx()
     45 {
     46   foo x;
     47   return foo.create<int>();
     48 }
     49 
     50 
     51 
     52 int main(int argc, char* argv[])
     53 {
     54   foo x;
     55   bar y(&x);
     56   x.create<int>();
     57   y.create<char *>();
     58   zzz<int>();
     59   yyy<int>();
     60   xxx();
     61   return 0;
     62 }
     63 


g++ y.cpp 하면 아래와 같이 나옵니다.

y.cpp: In function `T* zzz()':
y.cpp:35: error: parse error before `>' token
y.cpp: In function `int* yyy()':
y.cpp:41: error: parse error before `>' token

꼭 이소스만 그런것은 아니고 비슷한 경우의 다른 샘플에서는 bar::create<> 에 해당하는 함수가 컴파일이 안되는 경우도 있구요..

gcc 3.3.3 을 썼는데 gcc 자체의 버그가 아닌가 싶습니다. 혹시 여기에 대한 정보가 있는 분이 계신가요?

* VC++ 7.0 (.NET) 에서는 제대로 컴파일 됩니다.

bugiii의 이미지

41, 47 라인은 다른 문제때문에 일단 에러일 것 같습니다. 객체없이 멤버함수 호출을 못할테니까요... 그걸 접어두고 실험해 보았습니다.

이리 저리 머리를 굴리다가 결국 다음과 같이 하니 컴파일 에러없이 잘 동작하였습니다.

x.foo::create<T>()

이렇게 해본 저 자신도 이런 형태의 멤버함수 호출은 처음 봅니다... 어렴풋이 그렇게 해야 하겠다는 생각은 드는데 왜 그런지 딱 뭐라 말하기가...

근데, 이렇게 해도 되는건가요? 이런게 괜히 g++에만 되고 표준이 아닌 그런것은 아닐까요? 고수분의 시원한 답변 기다립니다.

singlet의 이미지

잘은 모르는 내용이긴 합니다만, 이런 경우 foo::create() 가 멤버 템플릿이므로 이렇게 써야 표준에 부합한다고 들었습니다. (왠지는 저도 잘 모릅니다만)

template <class T> T *zzz()
{
    foo x;
    return x.template create<T>();
}

template <class T> int *yyy()
{
    foo x;
    return x.template create<int>();
}

p.s. GCC 3.4.X 서부터 적용될 예정이었다고 들었는데 3.3.X 에서도 적용되는 모양이군요. 약간 의외네요.
mtorange의 이미지

bugiii wrote:
41, 47 라인은 다른 문제때문에 일단 에러일 것 같습니다. 객체없이 멤버함수 호출을 못할테니까요... 그걸 접어두고 실험해 보았습니다.

이리 저리 머리를 굴리다가 결국 다음과 같이 하니 컴파일 에러없이 잘 동작하였습니다.

x.foo::create<T>()

이렇게 해본 저 자신도 이런 형태의 멤버함수 호출은 처음 봅니다... 어렴풋이 그렇게 해야 하겠다는 생각은 드는데 왜 그런지 딱 뭐라 말하기가...

근데, 이렇게 해도 되는건가요? 이런게 괜히 g++에만 되고 표준이 아닌 그런것은 아닐까요? 고수분의 시원한 답변 기다립니다.

41, 47라인은 오타입니다. x.create.. 가 맞습니다.
그나저나 x.foo::create<T>() 는 좀 신기한 expression이긴하네요. ^^;

댓글 달기

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