public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug c++/14132] New: static template member definition fails
@ 2004-02-12 19:17 guillaume dot melquiond at ens-lyon dot fr
  2004-02-12 19:37 ` [Bug c++/14132] " gdr at integrable-solutions dot net
                   ` (6 more replies)
  0 siblings, 7 replies; 8+ messages in thread
From: guillaume dot melquiond at ens-lyon dot fr @ 2004-02-12 19:17 UTC (permalink / raw)
  To: gcc-bugs

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain, Size: 1784 bytes --]

Hi,

This bug is the same as PR11585 but I'm not convinced by its conclusion. However
I didn't know if I should have reopened the bug or created a new one.

The test-case is:

  template< class T > struct A { static int a; };
  int A< void >::a;

With GCC 3.3 and Intel CC 8.0, the code compiles just fine. But GCC 3.4
(20040211 snapshot) complains: "plouf.cc:2: error: too few
template-parameter-lists". In order for GCC 3.4 to accept the code, "template<>"
must be added in front of the second line (it's the solution suggested in PR11585).

Unfortunately, adding "template<>" does change the meaning of the line since GCC
will not create an instance of "A<void>::a" anymore and the following testcase
will not be linkable:

  template< class T > struct A { static int a; };
  template<> int A< void >::a;
  int main() { A< void >::a = 0; }

  /tmp/ccgh5JJQ.o(.text+0x1e): dans la fonction « main »:
  : undefined reference to `A<void>::a'

It fails to link with GCC 3.3, 3.4 and ICC 8.0. But removing the "template<>"
allows the program to cleanly compile and link with both GCC 3.3 and ICC 8.0. So
what's the solution?

Please consider this bug-report as a wish item for the C++ language improvements
section of http://gcc.gnu.org/gcc-3.4/changes.html since it is quite a common
case when programing with templates and static members.

-- 
           Summary: static template member definition fails
           Product: gcc
           Version: 3.4.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P2
         Component: c++
        AssignedTo: unassigned at gcc dot gnu dot org
        ReportedBy: guillaume dot melquiond at ens-lyon dot fr
                CC: gcc-bugs at gcc dot gnu dot org


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=14132


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [Bug c++/14132] New: static template member definition fails
  2004-02-12 19:17 [Bug c++/14132] New: static template member definition fails guillaume dot melquiond at ens-lyon dot fr
  2004-02-12 19:37 ` [Bug c++/14132] " gdr at integrable-solutions dot net
@ 2004-02-12 19:37 ` Gabriel Dos Reis
  2004-02-12 20:03 ` [Bug c++/14132] " guillaume dot melquiond at ens-lyon dot fr
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Gabriel Dos Reis @ 2004-02-12 19:37 UTC (permalink / raw)
  To: gcc-bugzilla; +Cc: gcc-bugs

"guillaume dot melquiond at ens-lyon dot fr" <gcc-bugzilla@gcc.gnu.org> writes:

| Hi,
| 
| This bug is the same as PR11585 but I'm not convinced by its conclusion. However
| I didn't know if I should have reopened the bug or created a new one.
| 
| The test-case is:
| 
|   template< class T > struct A { static int a; };
|   int A< void >::a;

The second line does not make sense.  Which is why I should ask the
question: What did you want to say by that line?

[...]

| It fails to link with GCC 3.3, 3.4 and ICC 8.0. But removing the "template<>"
| allows the program to cleanly compile and link with both GCC 3.3 and ICC 8.0. So
| what's the solution?

What did you mean to say by that construct?

-- Gaby


^ permalink raw reply	[flat|nested] 8+ messages in thread

* [Bug c++/14132] static template member definition fails
  2004-02-12 19:17 [Bug c++/14132] New: static template member definition fails guillaume dot melquiond at ens-lyon dot fr
@ 2004-02-12 19:37 ` gdr at integrable-solutions dot net
  2004-02-12 19:37 ` [Bug c++/14132] New: " Gabriel Dos Reis
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: gdr at integrable-solutions dot net @ 2004-02-12 19:37 UTC (permalink / raw)
  To: gcc-bugs


------- Additional Comments From gdr at integrable-solutions dot net  2004-02-12 19:37 -------
Subject: Re:  New: static template member definition fails

"guillaume dot melquiond at ens-lyon dot fr" <gcc-bugzilla@gcc.gnu.org> writes:

| Hi,
| 
| This bug is the same as PR11585 but I'm not convinced by its conclusion. However
| I didn't know if I should have reopened the bug or created a new one.
| 
| The test-case is:
| 
|   template< class T > struct A { static int a; };
|   int A< void >::a;

The second line does not make sense.  Which is why I should ask the
question: What did you want to say by that line?

[...]

| It fails to link with GCC 3.3, 3.4 and ICC 8.0. But removing the "template<>"
| allows the program to cleanly compile and link with both GCC 3.3 and ICC 8.0. So
| what's the solution?

What did you mean to say by that construct?

-- Gaby


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=14132


^ permalink raw reply	[flat|nested] 8+ messages in thread

* [Bug c++/14132] static template member definition fails
  2004-02-12 19:17 [Bug c++/14132] New: static template member definition fails guillaume dot melquiond at ens-lyon dot fr
  2004-02-12 19:37 ` [Bug c++/14132] " gdr at integrable-solutions dot net
  2004-02-12 19:37 ` [Bug c++/14132] New: " Gabriel Dos Reis
@ 2004-02-12 20:03 ` guillaume dot melquiond at ens-lyon dot fr
  2004-02-12 20:27 ` pinskia at gcc dot gnu dot org
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: guillaume dot melquiond at ens-lyon dot fr @ 2004-02-12 20:03 UTC (permalink / raw)
  To: gcc-bugs


------- Additional Comments From guillaume dot melquiond at ens-lyon dot fr  2004-02-12 20:03 -------
Standard 9.4.2 (static data members) says: "A declaration of a static data
member in its class definition is not a definition [...] The definition for a
static data member shall appear in a namespace scope enclosing the member's
class definition." This part of the standard doesn't say it applies to static
data members of template classes; but since 14.5.1.3 (static data members of
class templates) doesn't explain what the situation is (at least not in my
version), I have supposed 9.4.2 should apply (since A<void> is a class, isn't it?).

9.4.2 says this code is valid:

struct B { int b; } // the "false" definition of B::b
int B::b;           // the "real" definition, it is mandatory (9.4.2-5)

Now I'm trying to do exactly the same thing with the class A<void>. Since
A<void>::a "is not a definition" (and the linker is right to complain), I'm
trying to give the real definition of A<void>::a. GCC 3.3 and ICC 8.0 both
understand it is its real definition (as stated in 9.4.2); GCC 3.4 does not. And
adding "template<>" before the line does not create a "real" definition (since
the linker complains).

Hope I was clearer.

-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=14132


^ permalink raw reply	[flat|nested] 8+ messages in thread

* [Bug c++/14132] static template member definition fails
  2004-02-12 19:17 [Bug c++/14132] New: static template member definition fails guillaume dot melquiond at ens-lyon dot fr
                   ` (2 preceding siblings ...)
  2004-02-12 20:03 ` [Bug c++/14132] " guillaume dot melquiond at ens-lyon dot fr
@ 2004-02-12 20:27 ` pinskia at gcc dot gnu dot org
  2004-02-12 21:42 ` guillaume dot melquiond at ens-lyon dot fr
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: pinskia at gcc dot gnu dot org @ 2004-02-12 20:27 UTC (permalink / raw)
  To: gcc-bugs


------- Additional Comments From pinskia at gcc dot gnu dot org  2004-02-12 20:27 -------
This works and is what you really want:
  template< class T > struct A { static int a; };
  template<class T> int A< T>::a ;

-- 
           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|UNCONFIRMED                 |RESOLVED
         Resolution|                            |INVALID


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=14132


^ permalink raw reply	[flat|nested] 8+ messages in thread

* [Bug c++/14132] static template member definition fails
  2004-02-12 19:17 [Bug c++/14132] New: static template member definition fails guillaume dot melquiond at ens-lyon dot fr
                   ` (3 preceding siblings ...)
  2004-02-12 20:27 ` pinskia at gcc dot gnu dot org
@ 2004-02-12 21:42 ` guillaume dot melquiond at ens-lyon dot fr
  2004-02-13  0:59 ` gdr at integrable-solutions dot net
  2004-02-13  1:01 ` gdr at integrable-solutions dot net
  6 siblings, 0 replies; 8+ messages in thread
From: guillaume dot melquiond at ens-lyon dot fr @ 2004-02-12 21:42 UTC (permalink / raw)
  To: gcc-bugs


------- Additional Comments From guillaume dot melquiond at ens-lyon dot fr  2004-02-12 21:42 -------
Thanks, your reply has shown me what the correct solution is. Your solution is
not enough when there is more than one .o file. Indeed, this "template<class T>
def" syntax only defines classes when GCC sees the static member being accessed
in the current translation unit. So when the old code looks like:

  int A<void>::a;

it must be replaced by:

  template class A<void>;
  template<class T> int A<T>::a;

Since the compiler puts these variables in the "common" section, the linker
won't complain when there are duplicates (since "template<class T> def" will
unfortunately catch all uses of the static members).

Thanks.

-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=14132


^ permalink raw reply	[flat|nested] 8+ messages in thread

* [Bug c++/14132] static template member definition fails
  2004-02-12 19:17 [Bug c++/14132] New: static template member definition fails guillaume dot melquiond at ens-lyon dot fr
                   ` (4 preceding siblings ...)
  2004-02-12 21:42 ` guillaume dot melquiond at ens-lyon dot fr
@ 2004-02-13  0:59 ` gdr at integrable-solutions dot net
  2004-02-13  1:01 ` gdr at integrable-solutions dot net
  6 siblings, 0 replies; 8+ messages in thread
From: gdr at integrable-solutions dot net @ 2004-02-13  0:59 UTC (permalink / raw)
  To: gcc-bugs


------- Additional Comments From gdr at integrable-solutions dot net  2004-02-13 00:59 -------
Subject: Re:  static template member definition fails

"guillaume dot melquiond at ens-lyon dot fr" <gcc-bugzilla@gcc.gnu.org> writes:

| Standard 9.4.2 (static data members) says: "A declaration of a static data
| member in its class definition is not a definition [...] The definition for a
| static data member shall appear in a namespace scope enclosing the member's
| class definition." This part of the standard doesn't say it applies to static
| data members of template classes;

But, the standard certainly tells you the syntax of out-of-class
member definition of a template; it must start with the
template-header that declares the template parameters, just   like you
do it for any other member.

  template<class T>
    int A<T>::a;


| but since 14.5.1.3 (static data members of
| class templates) doesn't explain what the situation is (at least not in my
| version), I have supposed 9.4.2 should apply (since A<void> is a class, isn't it?).

A<void> is a -specialization- so you first need to provide the
general definition above; then you go on requesting either the whole
the explicit specialization or you just request the explicit
specialization of that static data member. 

| 9.4.2 says this code is valid:
| 
| struct B { int b; } // the "false" definition of B::b

There is nothing named '"false" definition'.  The above is a
declaration.

| int B::b;           // the "real" definition, it is mandatory (9.4.2-5)
| 
| Now I'm trying to do exactly the same thing with the class A<void>. Since
| A<void>::a "is not a definition" (and the linker is right to complain), I'm
| trying to give the real definition of A<void>::a.

OK.  See above for a solution.


The PR could be closed.  This is more a question to be asked on
comp.lang.c++.moderated than a bug with the compiler.

-- Gaby


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=14132


^ permalink raw reply	[flat|nested] 8+ messages in thread

* [Bug c++/14132] static template member definition fails
  2004-02-12 19:17 [Bug c++/14132] New: static template member definition fails guillaume dot melquiond at ens-lyon dot fr
                   ` (5 preceding siblings ...)
  2004-02-13  0:59 ` gdr at integrable-solutions dot net
@ 2004-02-13  1:01 ` gdr at integrable-solutions dot net
  6 siblings, 0 replies; 8+ messages in thread
From: gdr at integrable-solutions dot net @ 2004-02-13  1:01 UTC (permalink / raw)
  To: gcc-bugs


------- Additional Comments From gdr at integrable-solutions dot net  2004-02-13 01:01 -------
Subject: Re:  static template member definition fails

"guillaume dot melquiond at ens-lyon dot fr" <gcc-bugzilla@gcc.gnu.org> writes:

| Thanks, your reply has shown me what the correct solution is. Your solution is
| not enough when there is more than one .o file. Indeed, this "template<class T>
| def" syntax only defines classes when GCC sees the static member being accessed
| in the current translation unit.

That is called implicit instantiation and is not supposed to work as
explicit instantiation.

| So when the old code looks like:
| 
|   int A<void>::a;
| 
| it must be replaced by:
| 
|   template class A<void>;
|   template<class T> int A<T>::a;

Reverse the order:

   (1) provide the template definition of the static data member
   (2) instantiate the class.

-- Gaby


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=14132


^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2004-02-13  1:01 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2004-02-12 19:17 [Bug c++/14132] New: static template member definition fails guillaume dot melquiond at ens-lyon dot fr
2004-02-12 19:37 ` [Bug c++/14132] " gdr at integrable-solutions dot net
2004-02-12 19:37 ` [Bug c++/14132] New: " Gabriel Dos Reis
2004-02-12 20:03 ` [Bug c++/14132] " guillaume dot melquiond at ens-lyon dot fr
2004-02-12 20:27 ` pinskia at gcc dot gnu dot org
2004-02-12 21:42 ` guillaume dot melquiond at ens-lyon dot fr
2004-02-13  0:59 ` gdr at integrable-solutions dot net
2004-02-13  1:01 ` gdr at integrable-solutions dot net

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).