Weird difference between comeau and gcc/clang

  • Thread starter Johannes Schaub (litb)
  • Start date
J

Johannes Schaub (litb)

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!
 
J

James Kanze

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.
 
G

Gennaro Prota

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?
 
J

Johannes Schaub (litb)

James said:
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

Ian Collins

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?
 
J

Johannes Schaub (litb)

Ian said:
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?
 
I

Ian Collins

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?
 
G

Gil

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.

?
 
S

Steve Pope

Gil said:
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
 
J

Juha Nieminen

Gil said:
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?
 
J

Johannes Schaub (litb)

Gil said:
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.
 
J

Johannes Schaub (litb)

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?
 
V

Victor Bazarov

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
 
J

Johannes Schaub (litb)

Victor said:
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.
 
J

James Kanze

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.
 
J

James Kanze

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.
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.
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,982
Messages
2,570,185
Members
46,736
Latest member
AdolphBig6

Latest Threads

Top