Weird difference between comeau and gcc/clang

Discussion in 'C++' started by Johannes Schaub (litb), Oct 13, 2010.

  1. Both gcc and clang do not instantiate the struct definition. But comeau does

    template <typename T>
    void f()
    {
    struct haha {
    void g() { T t; }
    };
    }

    int main() {
    f<void>();
    }


    And comeau therefor says "T t;" is invalid because t is void. I always
    thought that local structs are immediately instantiated along with their
    function. But clang and GCC don't do so!

    Is GCC/Clang or Comeau correct? I deeply believe GCC and Clang are wrong on
    this!
    Johannes Schaub (litb), Oct 13, 2010
    #1
    1. Advertising

  2. Johannes Schaub (litb)

    James Kanze Guest

    On Oct 13, 8:59 pm, "Johannes Schaub (litb)" <>
    wrote:
    > Both gcc and clang do not instantiate the struct definition.
    > But comeau does


    > template <typename T>
    > void f()
    > {
    > struct haha {
    > void g() { T t; }
    > };
    > }


    > int main() {
    > f<void>();
    > }


    > And comeau therefor says "T t;" is invalid because t is void.
    > I always thought that local structs are immediately
    > instantiated along with their function. But clang and GCC
    > don't do so!


    > Is GCC/Clang or Comeau correct? I deeply believe GCC and Clang
    > are wrong on this!


    Typically, if compilers differ, Comeau is correct. In this
    case, however, I don't think so. Local structs are
    instantiated, but member functions are only instantiated if they
    are used, and your use of T is in the member function.

    --
    James Kanze
    James Kanze, Oct 14, 2010
    #2
    1. Advertising

  3. On 14/10/2010 10.47, James Kanze wrote:
    > On Oct 13, 8:59 pm, "Johannes Schaub (litb)" <>
    > wrote:
    >> Both gcc and clang do not instantiate the struct definition.
    >> But comeau does

    >
    >> template <typename T>
    >> void f()
    >> {
    >> struct haha {
    >> void g() { T t; }
    >> };
    >> }

    >
    >> int main() {
    >> f<void>();
    >> }

    >
    >> And comeau therefor says "T t;" is invalid because t is void.
    >> I always thought that local structs are immediately
    >> instantiated along with their function. But clang and GCC
    >> don't do so!

    >
    >> Is GCC/Clang or Comeau correct? I deeply believe GCC and Clang
    >> are wrong on this!

    >
    > Typically, if compilers differ, Comeau is correct. In this
    > case, however, I don't think so. Local structs are
    > instantiated, but member functions are only instantiated if they
    > are used, and your use of T is in the member function.


    But neither haha nor haha::g are templates. Why do you expect
    the behavior you describe?

    --
    Gennaro Prota | <https://sourceforge.net/projects/breeze/>
    Do you need expertise in C++? I'm available.
    Gennaro Prota, Oct 14, 2010
    #3
  4. James Kanze wrote:

    > On Oct 13, 8:59 pm, "Johannes Schaub (litb)" <>
    > wrote:
    >> Both gcc and clang do not instantiate the struct definition.
    >> But comeau does

    >
    >> template <typename T>
    >> void f()
    >> {
    >> struct haha {
    >> void g() { T t; }
    >> };
    >> }

    >
    >> int main() {
    >> f<void>();
    >> }

    >
    >> And comeau therefor says "T t;" is invalid because t is void.
    >> I always thought that local structs are immediately
    >> instantiated along with their function. But clang and GCC
    >> don't do so!

    >
    >> Is GCC/Clang or Comeau correct? I deeply believe GCC and Clang
    >> are wrong on this!

    >
    > Typically, if compilers differ, Comeau is correct. In this
    > case, however, I don't think so. Local structs are
    > instantiated, but member functions are only instantiated if they
    > are used, and your use of T is in the member function.
    >


    I was not able to get a clear opinion about this. I find it difficult find a
    clear statement about it in the IS.
    Johannes Schaub (litb), Oct 14, 2010
    #4
  5. Johannes Schaub (litb)

    Ian Collins Guest

    On 10/15/10 09:17 AM, Johannes Schaub (litb) wrote:
    > James Kanze wrote:
    >
    >> On Oct 13, 8:59 pm, "Johannes Schaub (litb)"<>
    >> wrote:
    >>> Both gcc and clang do not instantiate the struct definition.
    >>> But comeau does

    >>
    >>> template<typename T>
    >>> void f()
    >>> {
    >>> struct haha {
    >>> void g() { T t; }
    >>> };
    >>> }

    >>
    >>> int main() {
    >>> f<void>();
    >>> }

    >>
    >>> And comeau therefor says "T t;" is invalid because t is void.
    >>> I always thought that local structs are immediately
    >>> instantiated along with their function. But clang and GCC
    >>> don't do so!

    >>
    >>> Is GCC/Clang or Comeau correct? I deeply believe GCC and Clang
    >>> are wrong on this!

    >>
    >> Typically, if compilers differ, Comeau is correct. In this
    >> case, however, I don't think so. Local structs are
    >> instantiated, but member functions are only instantiated if they
    >> are used, and your use of T is in the member function.
    >>

    >
    > I was not able to get a clear opinion about this. I find it difficult find a
    > clear statement about it in the IS.


    I thought James' reply was clear and unambiguous. Class template member
    functions are only instantiated if they are used. This feature is often
    exploited to get different behaviour depending on the template argument.

    Or is the confusion whether a local class in a function template a class
    template?

    --
    Ian Collins
    Ian Collins, Oct 14, 2010
    #5
  6. Ian Collins wrote:

    > On 10/15/10 09:17 AM, Johannes Schaub (litb) wrote:
    >> James Kanze wrote:
    >>
    >>> On Oct 13, 8:59 pm, "Johannes Schaub (litb)"<>
    >>> wrote:
    >>>> Both gcc and clang do not instantiate the struct definition.
    >>>> But comeau does
    >>>
    >>>> template<typename T>
    >>>> void f()
    >>>> {
    >>>> struct haha {
    >>>> void g() { T t; }
    >>>> };
    >>>> }
    >>>
    >>>> int main() {
    >>>> f<void>();
    >>>> }
    >>>
    >>>> And comeau therefor says "T t;" is invalid because t is void.
    >>>> I always thought that local structs are immediately
    >>>> instantiated along with their function. But clang and GCC
    >>>> don't do so!
    >>>
    >>>> Is GCC/Clang or Comeau correct? I deeply believe GCC and Clang
    >>>> are wrong on this!
    >>>
    >>> Typically, if compilers differ, Comeau is correct. In this
    >>> case, however, I don't think so. Local structs are
    >>> instantiated, but member functions are only instantiated if they
    >>> are used, and your use of T is in the member function.
    >>>

    >>
    >> I was not able to get a clear opinion about this. I find it difficult
    >> find a clear statement about it in the IS.

    >
    > I thought James' reply was clear and unambiguous. Class template member
    > functions are only instantiated if they are used. This feature is often
    > exploited to get different behaviour depending on the template argument.
    >
    > Or is the confusion whether a local class in a function template a class
    > template?
    >


    I am looking for a statement in the IS about it. I haven't been successful
    yet. I'm aware about the principle you mention for class template member
    functions. Is there a statement about local classes too?

    In particular, is an instantiated local class of a function template
    specialization a class template specialization? In the list of 14.7/2, ("A
    .... is called an instantiated ..."), I do not find local classes.

    Ultimately, what paragraphs will the comeau/EDG developers take, and what
    paragraphs will GCC and Clang take?
    Johannes Schaub (litb), Oct 14, 2010
    #6
  7. Johannes Schaub (litb)

    Ian Collins Guest

    On 10/15/10 07:24 AM, Gennaro Prota wrote:
    > On 14/10/2010 10.47, James Kanze wrote:
    >> On Oct 13, 8:59 pm, "Johannes Schaub (litb)"<>
    >> wrote:
    >>> Both gcc and clang do not instantiate the struct definition.
    >>> But comeau does

    >>
    >>> template<typename T>
    >>> void f()
    >>> {
    >>> struct haha {
    >>> void g() { T t; }
    >>> };
    >>> }

    >>
    >>> int main() {
    >>> f<void>();
    >>> }

    >>
    >>> And comeau therefor says "T t;" is invalid because t is void.
    >>> I always thought that local structs are immediately
    >>> instantiated along with their function. But clang and GCC
    >>> don't do so!

    >>
    >>> Is GCC/Clang or Comeau correct? I deeply believe GCC and Clang
    >>> are wrong on this!

    >>
    >> Typically, if compilers differ, Comeau is correct. In this
    >> case, however, I don't think so. Local structs are
    >> instantiated, but member functions are only instantiated if they
    >> are used, and your use of T is in the member function.

    >
    > But neither haha nor haha::g are templates. Why do you expect
    > the behavior you describe?


    The question appears to be is a local class in a function template a
    class template?

    Perhaps comp.std.c++ is the best place to post this question?

    --
    Ian Collins
    Ian Collins, Oct 14, 2010
    #7
  8. Johannes Schaub (litb)

    Gil Guest

    On Oct 13, 3:59 pm, "Johannes Schaub (litb)" <>
    wrote:
    > Both gcc and clang do not instantiate the struct definition. But comeau does
    >
    > template <typename T>
    > void f()
    > {
    >   struct haha {
    >     void g() { T t; }
    >   };
    >
    > }
    >
    > int main() {
    >   f<void>();
    >
    > }
    >
    > And comeau therefor says "T t;" is invalid because t is void. I always
    > thought that local structs are immediately instantiated along with their
    > function. But clang and GCC don't do so!
    >
    > Is GCC/Clang or Comeau correct? I deeply believe GCC and Clang are wrong on
    > this!


    if Comeau diagnostics an error on your code then Comeau is right.
    local classes cannot be class templates; template names have
    linkage(14.4), local classes don't(9.8.1).

    for zealots' delight maybe an explicit wording should be added to 9.8,
    something like

    9.8.5 A local class shall not be a template.

    ?

    --
    gil
    Gil, Oct 15, 2010
    #8
  9. Johannes Schaub (litb)

    Steve Pope Guest

    Gil <> wrote:

    >On Oct 13, 3:59 pm, "Johannes Schaub (litb)" <>
    >wrote:
    >> Both gcc and clang do not instantiate the struct definition. But comeau does
    >>
    >> template <typename T>
    >> void f()
    >> {
    >>   struct haha {
    >>     void g() { T t; }
    >>   };
    >>
    >> }
    >>
    >> int main() {
    >>   f<void>();
    >>
    >> }
    >>
    >> And comeau therefor says "T t;" is invalid because t is void. I always
    >> thought that local structs are immediately instantiated along with their
    >> function. But clang and GCC don't do so!
    >>
    >> Is GCC/Clang or Comeau correct? I deeply believe GCC and Clang are wrong on
    >> this!

    >
    >if Comeau diagnostics an error on your code then Comeau is right.
    >local classes cannot be class templates; template names have
    >linkage(14.4), local classes don't(9.8.1).


    Does GCC still not issue a warning using -pedantic?


    Steve
    Steve Pope, Oct 15, 2010
    #9
  10. Gil <> wrote:
    > On Oct 13, 3:59 pm, "Johannes Schaub (litb)" <>
    > wrote:
    >> Both gcc and clang do not instantiate the struct definition. But comeau does
    >>
    >> template <typename T>
    >> void f()
    >> {
    >>   struct haha {
    >>     void g() { T t; }
    >>   };
    >>
    >> }
    >>
    >> int main() {
    >>   f<void>();
    >>
    >> }
    >>
    >> And comeau therefor says "T t;" is invalid because t is void. I always
    >> thought that local structs are immediately instantiated along with their
    >> function. But clang and GCC don't do so!
    >>
    >> Is GCC/Clang or Comeau correct? I deeply believe GCC and Clang are wrong on
    >> this!

    >
    > if Comeau diagnostics an error on your code then Comeau is right.
    > local classes cannot be class templates; template names have
    > linkage(14.4), local classes don't(9.8.1).


    If Comeau is always right, and local classes can indeed not be
    templates, why doesn't Comeau say so, rather then complaining about
    a type definition inside a member function of such class?

    Could it be that Comeau happens to refuse to compile this example
    by pure chance, rather than explicitly having a rule against local
    template classes?
    Juha Nieminen, Oct 15, 2010
    #10
  11. Gil wrote:

    > On Oct 13, 3:59 pm, "Johannes Schaub (litb)" <>
    > wrote:
    >> Both gcc and clang do not instantiate the struct definition. But comeau
    >> does
    >>
    >> template <typename T>
    >> void f()
    >> {
    >> struct haha {
    >> void g() { T t; }
    >> };
    >>
    >> }
    >>
    >> int main() {
    >> f<void>();
    >>
    >> }
    >>
    >> And comeau therefor says "T t;" is invalid because t is void. I always
    >> thought that local structs are immediately instantiated along with their
    >> function. But clang and GCC don't do so!
    >>
    >> Is GCC/Clang or Comeau correct? I deeply believe GCC and Clang are wrong
    >> on this!

    >
    > if Comeau diagnostics an error on your code then Comeau is right.
    > local classes cannot be class templates; template names have
    > linkage(14.4), local classes don't(9.8.1).
    >
    > for zealots' delight maybe an explicit wording should be added to 9.8,
    > something like
    >
    > 9.8.5 A local class shall not be a template.
    >


    The local class in my code was not a template. I did not put a
    "template<...>" before it. It was a non-template local class defined in a
    function template.
    Johannes Schaub (litb), Oct 15, 2010
    #11
  12. Johannes Schaub (litb) wrote:

    > Gil wrote:
    >
    >> On Oct 13, 3:59 pm, "Johannes Schaub (litb)" <>
    >> wrote:
    >>> Both gcc and clang do not instantiate the struct definition. But comeau
    >>> does
    >>>
    >>> template <typename T>
    >>> void f()
    >>> {
    >>> struct haha {
    >>> void g() { T t; }
    >>> };
    >>>
    >>> }
    >>>
    >>> int main() {
    >>> f<void>();
    >>>
    >>> }
    >>>
    >>> And comeau therefor says "T t;" is invalid because t is void. I always
    >>> thought that local structs are immediately instantiated along with their
    >>> function. But clang and GCC don't do so!
    >>>
    >>> Is GCC/Clang or Comeau correct? I deeply believe GCC and Clang are wrong
    >>> on this!

    >>
    >> if Comeau diagnostics an error on your code then Comeau is right.


    I don't follow that logic. Am I applying your logic correctly below?

    "if GCC diagnostics [sic] an error on your code then GCC is right."

    Both can't be right. What is it that I don't understand about your logic?
    Johannes Schaub (litb), Oct 15, 2010
    #12
  13. On 10/15/2010 1:28 PM, Johannes Schaub (litb) wrote:
    > Gil wrote:
    >
    >> On Oct 13, 3:59 pm, "Johannes Schaub (litb)"<>
    >> wrote:
    >>> Both gcc and clang do not instantiate the struct definition. But comeau
    >>> does
    >>>
    >>> template<typename T>
    >>> void f()
    >>> {
    >>> struct haha {
    >>> void g() { T t; }
    >>> };
    >>>
    >>> }
    >>>
    >>> int main() {
    >>> f<void>();
    >>>
    >>> }
    >>>
    >>> And comeau therefor says "T t;" is invalid because t is void. I always
    >>> thought that local structs are immediately instantiated along with their
    >>> function. But clang and GCC don't do so!
    >>>
    >>> Is GCC/Clang or Comeau correct? I deeply believe GCC and Clang are wrong
    >>> on this!

    >>
    >> if Comeau diagnostics an error on your code then Comeau is right.
    >> local classes cannot be class templates; template names have
    >> linkage(14.4), local classes don't(9.8.1).
    >>
    >> for zealots' delight maybe an explicit wording should be added to 9.8,
    >> something like
    >>
    >> 9.8.5 A local class shall not be a template.
    >>

    >
    > The local class in my code was not a template. I did not put a
    > "template<...>" before it. It was a non-template local class defined in a
    > function template.


    Well, the problem is that for every instantiation of your function
    template there would be an instantiation of the local class, would there
    not? Since its internal structure does depend on the template argument,
    it de facto becomes a template. Just like a local variable of type T
    would. While it's not a template variable (there is no such thing), it
    would be a template since it's part of a template. Like a member
    function of a class template would still be a template even though you
    wouldn't [need to] declare it 'template'. Right?

    V
    --
    I do not respond to top-posted replies, please don't ask
    Victor Bazarov, Oct 15, 2010
    #13
  14. Victor Bazarov wrote:

    > On 10/15/2010 1:28 PM, Johannes Schaub (litb) wrote:
    >> Gil wrote:
    >>
    >>> On Oct 13, 3:59 pm, "Johannes Schaub (litb)"<>
    >>> wrote:
    >>>> Both gcc and clang do not instantiate the struct definition. But comeau
    >>>> does
    >>>>
    >>>> template<typename T>
    >>>> void f()
    >>>> {
    >>>> struct haha {
    >>>> void g() { T t; }
    >>>> };
    >>>>
    >>>> }
    >>>>
    >>>> int main() {
    >>>> f<void>();
    >>>>
    >>>> }
    >>>>
    >>>> And comeau therefor says "T t;" is invalid because t is void. I always
    >>>> thought that local structs are immediately instantiated along with
    >>>> their function. But clang and GCC don't do so!
    >>>>
    >>>> Is GCC/Clang or Comeau correct? I deeply believe GCC and Clang are
    >>>> wrong on this!
    >>>
    >>> if Comeau diagnostics an error on your code then Comeau is right.
    >>> local classes cannot be class templates; template names have
    >>> linkage(14.4), local classes don't(9.8.1).
    >>>
    >>> for zealots' delight maybe an explicit wording should be added to 9.8,
    >>> something like
    >>>
    >>> 9.8.5 A local class shall not be a template.
    >>>

    >>
    >> The local class in my code was not a template. I did not put a
    >> "template<...>" before it. It was a non-template local class defined in a
    >> function template.

    >
    > Well, the problem is that for every instantiation of your function
    > template there would be an instantiation of the local class, would there
    > not? Since its internal structure does depend on the template argument,
    > it de facto becomes a template.


    It will then depend on template parameters. I do not see how that makes it a
    template though. Values depend on types. Is a value a type?

    > [...] it would be a template since it's part of a template.


    I think I do not agree. Why will it be a template just because it's part of
    a template? An int data member is not a class just because it is part of a
    class.

    > Like a member function of a class template would still be a template even

    though you wouldn't [need to] declare it 'template'. Right?
    >


    I do disagree to this too. A member function of a class template is a
    function. It depends on template parameters (its context is dependent).

    I also disagree to the note in [temp.mem.func]/p1 that says "declares three
    function templates". It declares three member functions. They are not member
    templates.
    Johannes Schaub (litb), Oct 15, 2010
    #14
  15. Johannes Schaub (litb)

    James Kanze Guest

    On Oct 14, 9:17 pm, "Johannes Schaub (litb)" <>
    wrote:
    > James Kanze wrote:
    > > On Oct 13, 8:59 pm, "Johannes Schaub (litb)" <>
    > > wrote:
    > >> Both gcc and clang do not instantiate the struct definition.
    > >> But comeau does


    > >> template <typename T>
    > >> void f()
    > >> {
    > >> struct haha {
    > >> void g() { T t; }
    > >> };
    > >> }


    > >> int main() {
    > >> f<void>();
    > >> }


    > >> And comeau therefor says "T t;" is invalid because t is void.
    > >> I always thought that local structs are immediately
    > >> instantiated along with their function. But clang and GCC
    > >> don't do so!


    > >> Is GCC/Clang or Comeau correct? I deeply believe GCC and Clang
    > >> are wrong on this!


    > > Typically, if compilers differ, Comeau is correct. In this
    > > case, however, I don't think so. Local structs are
    > > instantiated, but member functions are only instantiated if they
    > > are used, and your use of T is in the member function.


    > I was not able to get a clear opinion about this. I find it
    > difficult find a clear statement about it in the IS.


    It's spread out a little, but §14.7.1/2 has "Unless a function
    template specialization has been explicitly instantiated or
    explicitly specialized, the function template specialization is
    implicitly instantiated when the specialization is referenced in
    a context that requires a function definition to exist", and
    §3.2 describes what it means to be used, and more precisely,
    when a function definition is required to exist.

    In your case, there's nothing which requires the function
    definition to exist, so the compiler shouldn't instantiate it.
    Call the function, take its address, or make it virtual, and the
    situation changes.

    Note that this is a very important rule with regards to the
    standard library. std::list, for example, contains a function
    sort, which uses the < operator on the object type; if sort were
    instantiated even when it was never called, you couldn't put
    objects which didn't support < in an std::list.

    --
    James Kanze
    James Kanze, Oct 18, 2010
    #15
  16. Johannes Schaub (litb)

    James Kanze Guest

    On Oct 15, 7:32 pm, "Johannes Schaub (litb)" <>
    wrote:
    > Victor Bazarov wrote:
    > > On 10/15/2010 1:28 PM, Johannes Schaub (litb) wrote:
    > >> Gil wrote:
    > >>> 9.8.5 A local class shall not be a template.


    > >> The local class in my code was not a template. I did not
    > >> put a "template<...>" before it. It was a non-template
    > >> local class defined in a function template.


    > > Well, the problem is that for every instantiation of your
    > > function template there would be an instantiation of the
    > > local class, would there not? Since its internal structure
    > > does depend on the template argument, it de facto becomes
    > > a template.


    > It will then depend on template parameters. I do not see how
    > that makes it a template though. Values depend on types. Is
    > a value a type?


    > > [...] it would be a template since it's part of a template.


    > I think I do not agree. Why will it be a template just because
    > it's part of a template? An int data member is not a class
    > just because it is part of a class.


    > > Like a member function of a class template would still be
    > > a template even


    > though you wouldn't [need to] declare it 'template'. Right?


    > I do disagree to this too. A member function of a class
    > template is a function. It depends on template parameters (its
    > context is dependent).


    > I also disagree to the note in [temp.mem.func]/p1 that says
    > "declares three function templates". It declares three member
    > functions. They are not member templates.


    I fear that the standard isn't as clear (or as coherent) as one
    might like. Depending on where you're looking, context makes it
    very clear that 1) declarations nested in a template are only
    templates if they are declared as such (e.g. friends), and 2)
    declarations nested in a template are themselves templates (any
    time the standard talks about instantiation). In this case,
    we're talking about instantiation, so the latter use applies,
    and the local class and function are templates. Or not; the
    standard doesn't seem really clear on this point.

    --
    James Kanze
    James Kanze, Oct 18, 2010
    #16
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. jakk
    Replies:
    4
    Views:
    12,053
  2. Rasmus Johansen
    Replies:
    4
    Views:
    365
    Victor Bazarov
    Oct 18, 2007
  3. werasm
    Replies:
    4
    Views:
    350
    James Kanze
    Nov 30, 2009
  4. haziz

    Clang vs. GCC: Compare & Contrast?

    haziz, Mar 23, 2012, in forum: C Programming
    Replies:
    3
    Views:
    1,131
    Jens Gustedt
    Mar 23, 2012
  5. Lynn McGuire
    Replies:
    0
    Views:
    193
    Lynn McGuire
    Mar 15, 2013
Loading...

Share This Page