public inbox for gcc@gcc.gnu.org
 help / color / mirror / Atom feed
* Static members in templates in egcs-1.0.1
@ 1998-01-12 20:31 Erik Corry
  1998-01-14  0:45 ` Lassi A. Tuura
                   ` (2 more replies)
  0 siblings, 3 replies; 9+ messages in thread
From: Erik Corry @ 1998-01-12 20:31 UTC (permalink / raw)
  To: egcs

Hi,

I obtained egcs-1.0.1 and compiled it with the naive

./configure
make
make install

on my i586-pc-linux-gnu system with glibc-2.0.5c-10, gcc-2.7.2.3-8
and binutils-2.8.1.0.1-1 installed. It seems I can now use
egcs as /usr/local/bin/gcc, which is cool.

But it seems that static members of templates still don't work:

  template <class T>
  struct B
  {
    static T mycounter = 0;           // with static - doesn't work with egcs
    //T mycounter;                    // without static - works with egcs
    void IncCounter() {mycounter++;}
  };
  
  int
  main()
  {
    B<int> a;
    a.IncCounter();
    return 0;
  }
  
when I compile with

  /usr/local/bin/gcc -o smt static_simple.cpp

I get

  /tmp/cca283291.o: In function `B<int>::IncCounter(void)':
  /tmp/cca283291.o(.B<int>::gnu.linkonce.t.IncCounter(void)+0x8): undefined reference to `B<int>::mycounter'

with -v, that's

  Reading specs from /usr/local/lib/gcc-lib/i586-pc-linux-gnu/egcs-2.90.23/specs
  gcc version egcs-2.90.23 980102 (egcs-1.0.1 release)
   /usr/local/lib/gcc-lib/i586-pc-linux-gnu/egcs-2.90.23/cpp -lang-c++ -v -undef -D__GNUC__=2 -D__GNUG__=2 -D__cplusplus -D__GNUC_MINOR__=90 -D__ELF__ -Dunix -Dlinux -D__ELF__ -D__unix__ -D__linux__ -D__unix -D__linux -Asystem(posix) -D__EXCEPTIONS -Di386 -Di586 -Asystem(unix) -Acpu(i386) -Amachine(i386) -D__i386__ -D__i586__ -Asystem(unix) -Acpu(i386) -Amachine(i386) static_simple.cpp /tmp/cca28614.ii
  GNU CPP version egcs-2.90.23 980102 (egcs-1.0.1 release) (i386 Linux/ELF)
  #include "..." search starts here:
  #include <...> search starts here:
   /usr/local/include
   /usr/local/i586-pc-linux-gnu/include
   /usr/local/lib/gcc-lib/i586-pc-linux-gnu/egcs-2.90.23/include
   /usr/include
  End of search list.
   /usr/local/lib/gcc-lib/i586-pc-linux-gnu/egcs-2.90.23/cc1plus /tmp/cca28614.ii -quiet -dumpbase static_simple.cc -version -o /tmp/cca28614.s
  GNU C++ version egcs-2.90.23 980102 (egcs-1.0.1 release) (i586-pc-linux-gnu) compiled by GNU C version 2.7.2.3.
   as -V -Qy -o /tmp/cca286141.o /tmp/cca28614.s
  GNU assembler version 2.8.1 (i686-pc-linux-gnu), using BFD version linux-2.8.1.0.1
   /usr/local/lib/gcc-lib/i586-pc-linux-gnu/egcs-2.90.23/ld -m elf_i386 -dynamic-linker /lib/ld-linux.so.2 -o smt /usr/lib/crt1.o /usr/lib/crti.o /usr/local/lib/gcc-lib/i586-pc-linux-gnu/egcs-2.90.23/crtbegin.o -L/usr/local/lib/gcc-lib/i586-pc-linux-gnu/egcs-2.90.23 -L/usr/local/lib /tmp/cca286141.o -lgcc -lc -lgcc /usr/local/lib/gcc-lib/i586-pc-linux-gnu/egcs-2.90.23/crtend.o /usr/lib/crtn.o
  /tmp/cca286141.o: In function `B<int>::IncCounter(void)':
  /tmp/cca286141.o(.B<int>::gnu.linkonce.t.IncCounter(void)+0x8): undefined reference to `B<int>::mycounter'
  collect2: ld returned 1 exit status


So perhaps:

* I installed it wrong
  I couldn't find any egcs-specific installation instructions
  so I used the ones in the toplevel README.

* It just doesn't work yet

* I misunderstood how statics in templates were supposed to work

* I need -frepo or something - there doesn't seem to be much
  in the doc on this either. When I use -frepo I get .rpo files,
  - do I need to tell the linker to use them?

or

* Something else.

-- 
Erik Corry

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

* Re: Static members in templates in egcs-1.0.1
  1998-01-12 20:31 Static members in templates in egcs-1.0.1 Erik Corry
@ 1998-01-14  0:45 ` Lassi A. Tuura
  1998-01-14  4:17 ` Mark Mitchell
  1998-01-14  4:17 ` Joe Buck
  2 siblings, 0 replies; 9+ messages in thread
From: Lassi A. Tuura @ 1998-01-14  0:45 UTC (permalink / raw)
  To: Erik Corry; +Cc: egcs

Erik Corry wrote:
>   template <class T>
>   struct B
>   {
>     static T mycounter = 0;           // with static - doesn't work with egcs
>     //T mycounter;                    // without static - works with egcs
>     void IncCounter() {mycounter++;}
>   };

This is not valid C++.  You should write:
    template <class T> struct B {
      static T mycounter;
      void IncCounter() { mycounter++; }
    };
    template <class T> T B<T>::mycounter = 0;

Cheers,
//lat
-- 
Lassi.Tuura@cern.ch          There's no sunrise without a night

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

* Re: Static members in templates in egcs-1.0.1
  1998-01-12 20:31 Static members in templates in egcs-1.0.1 Erik Corry
  1998-01-14  0:45 ` Lassi A. Tuura
  1998-01-14  4:17 ` Mark Mitchell
@ 1998-01-14  4:17 ` Joe Buck
  1998-01-14  4:17   ` Erik Corry
  2 siblings, 1 reply; 9+ messages in thread
From: Joe Buck @ 1998-01-14  4:17 UTC (permalink / raw)
  To: Erik Corry; +Cc: egcs

> I obtained egcs-1.0.1 and compiled it with the naive
> 
> ./configure
> make
> make install
> 
> on my i586-pc-linux-gnu system with glibc-2.0.5c-10, gcc-2.7.2.3-8
> and binutils-2.8.1.0.1-1 installed. It seems I can now use
> egcs as /usr/local/bin/gcc, which is cool.
> 
> But it seems that static members of templates still don't work:

Yes they do, if you use the correct syntax.

You aren't writing correct C++ code (though egcs should issue a diagnostic
for what you are writing: putting 'static T mycounter = 0' in a class
declaration is invalid C++).  You must both declare and define a static
member, and you can't initialize a static member at the point of
declaration.

I think the reason you aren't getting a message is because of a GNU
extension (permitting initialization of members within classes) that
has suffered from bit rot (no one ever tried this case).  It would be
best to just diagnose your code as an error, since it isn't going to work.

Here's how to write the code:

template <class T>
struct B
{
    static T mycounter;			// declare B<T>::mycounter
    void IncCounter() {mycounter++;}
};

// it's a common mistake for people not to write the following -- some
// older compilers will create the equivalent of 0-initialized static
// members, but it is an error to rely on this:

template <class T>
T B<T>::mycounter = 0;			// define B<T>::mycounter

int main()
{
     B<int> a;
     a.IncCounter();
     return 0;
}

original code:
>   template <class T>
>   struct B
>   {
>     static T mycounter = 0;           // with static - doesn't work with egcs
>     //T mycounter;                    // without static - works with egcs
>     void IncCounter() {mycounter++;}
>   };
>   
>   int
>   main()
>   {
>     B<int> a;
>     a.IncCounter();
>     return 0;
>   }

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

* Static members in templates in egcs-1.0.1
  1998-01-12 20:31 Static members in templates in egcs-1.0.1 Erik Corry
  1998-01-14  0:45 ` Lassi A. Tuura
@ 1998-01-14  4:17 ` Mark Mitchell
  1998-01-14 23:17   ` Joe Buck
  1998-01-14 23:17   ` dave madden
  1998-01-14  4:17 ` Joe Buck
  2 siblings, 2 replies; 9+ messages in thread
From: Mark Mitchell @ 1998-01-14  4:17 UTC (permalink / raw)
  To: Erik Corry; +Cc: egcs

>>>>> "Erik" == Erik Corry <erik@arbat.com> writes:

    Erik>   template <class T> struct B { static T mycounter = 0; //
    Erik> with static - doesn't work with egcs //T mycounter; //
    Erik> without static - works with egcs void IncCounter()
    Erik> {mycounter++;} };
  
    Erik>   int main() { B<int> a; a.IncCounter(); return 0; }

As with static data members in non-templates, you need a definition of
the static data member at file-scope:

template <class T>
T B<T>::mycounter;

If you initialize the data member in-class, you should not initialize
it at file-scope.  (Currently, egcs doesn't issue an error message for
this, but I'm going to submit a patch to make sure it does real soon
now.)  

Note that in theory, you should not use in-class initialization with
non-const static data members; with -pedantic, g++ correctly says:

supernova% g++ -pedantic test.C
test.C:6: warning: ANSI C++ forbids in-class initialization of
non-const static member `mycounter'


-- 
Mark Mitchell		mmitchell@usa.net
Stanford University	http://www.stanford.edu


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

* Re: Static members in templates in egcs-1.0.1
  1998-01-14  4:17 ` Joe Buck
@ 1998-01-14  4:17   ` Erik Corry
  0 siblings, 0 replies; 9+ messages in thread
From: Erik Corry @ 1998-01-14  4:17 UTC (permalink / raw)
  To: Joe Buck; +Cc: egcs

On Tue, Jan 13, 1998 at 09:51:13AM -0800, Joe Buck wrote:
> Erik Corry 
> > But it seems that static members of templates still don't work:
> 
> Yes they do, if you use the correct syntax.

Ooops! Thanks for the correction.

> I think the reason you aren't getting a message is because of a GNU
> extension (permitting initialization of members within classes) that
> has suffered from bit rot (no one ever tried this case).  It would be
> best to just diagnose your code as an error, since it isn't going to work.

It seems it does work, if you also have the file-scope declaration
(without initialisation), so it's going to be difficult to warn about.

According to the comments in in cp/decl.c:

      /* Motion 10 at San Diego: If a static const integral data
         member is initialized with an integral constant
         expression, the initializer may appear either in the
         declaration (within the class), or in the definition,
         but not both.  If it appears in the class, the member is
         a member constant.  The file-scope definition is always
         required.  */

so it is allowed (ie not a GNU extension) for const integral
types. One real 'bug' is that:

struct F
{
  static int t = 1;
};

int F::t = 0;

will silently override the initialisation in the class declaration
and use the file-scope one, even with -Wall. If you leave the
initialisation off one of the places it works though. The same
applies with templates.

I will now go back to lurking.

-- 
Erik Corry erik@arbat.com

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

* Re: Static members in templates in egcs-1.0.1
  1998-01-14  4:17 ` Mark Mitchell
  1998-01-14 23:17   ` Joe Buck
@ 1998-01-14 23:17   ` dave madden
  1998-01-15 16:06     ` Joe Buck
  1998-01-15 16:06     ` Mark Mitchell
  1 sibling, 2 replies; 9+ messages in thread
From: dave madden @ 1998-01-14 23:17 UTC (permalink / raw)
  To: mmitchell; +Cc: egcs

 =>supernova% g++ -pedantic test.C
 =>test.C:6: warning: ANSI C++ forbids in-class initialization of
 =>non-const static member `mycounter'

I've been trying to find out for a while: does the C++ spec allow you
to define static consts in the class definition?  Egcs & g++ do, but
all the compilers I've tried on NT complain.  Here's what I'd like to
do:

template <class T> class foo {
	class bar {
		int		 xxx;
		T		 ttt;
	} ;
  public:
	static const size_t BAR_SIZE = sizeof(bar);
	static const int T_OFFSET = (int)(&((bar *)0)->ttt);
	// ... and various other address, padding, etc. calculations
} ;

Am I legal?

Thanks,
d.

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

* Re: Static members in templates in egcs-1.0.1
  1998-01-14  4:17 ` Mark Mitchell
@ 1998-01-14 23:17   ` Joe Buck
  1998-01-14 23:17   ` dave madden
  1 sibling, 0 replies; 9+ messages in thread
From: Joe Buck @ 1998-01-14 23:17 UTC (permalink / raw)
  To: mmitchell; +Cc: erik, egcs

> Note that in theory, you should not use in-class initialization with
> non-const static data members; with -pedantic, g++ correctly says:
> 
> supernova% g++ -pedantic test.C
> test.C:6: warning: ANSI C++ forbids in-class initialization of
> non-const static member `mycounter'

Since g++ does not generate correct code for this case (using the
in-class initialization for static template data members), it may
as well always issue an error.  I think that now that ANSI supports
the most useful case (a static const member can be initialized in the
class declaration) we should get rid of the other cases.




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

* Re: Static members in templates in egcs-1.0.1
  1998-01-14 23:17   ` dave madden
@ 1998-01-15 16:06     ` Joe Buck
  1998-01-15 16:06     ` Mark Mitchell
  1 sibling, 0 replies; 9+ messages in thread
From: Joe Buck @ 1998-01-15 16:06 UTC (permalink / raw)
  To: dave madden; +Cc: mmitchell, egcs

> I've been trying to find out for a while: does the C++ spec allow you
> to define static consts in the class definition?  Egcs & g++ do, but
> all the compilers I've tried on NT complain.

Yes (the standard does allow it), but it is a fairly recent change
(meaning that it isn't widely portable yet).

If you need your code to compile on a variety of C++ compilers I'm
afraid you can't use that feature yet.

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

* Re: Static members in templates in egcs-1.0.1
  1998-01-14 23:17   ` dave madden
  1998-01-15 16:06     ` Joe Buck
@ 1998-01-15 16:06     ` Mark Mitchell
  1 sibling, 0 replies; 9+ messages in thread
From: Mark Mitchell @ 1998-01-15 16:06 UTC (permalink / raw)
  To: dave madden; +Cc: egcs

    dave> I've been trying to find out for a while: does the C++ spec
    dave> allow you to define static consts in the class definition?
    dave> Egcs & g++ do, but all the compilers I've tried on NT
    dave> complain.  Here's what I'd like to do:

[ class.static.data ]

4 If a static data member is of const integral or const enumeration
type, its declaration in the class definition can specify a constant-
initializer which shall be an integral constant expression
(_expr.const_).  In that case, the member can appear in integral con-
stant expressions within its scope.  The member shall still be defined
in a namespace scope if it is used in the program and the namespace
scope definition shall not contain an initializer.


-- 
Mark Mitchell		mmitchell@usa.net
Stanford University	http://www.stanford.edu


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

end of thread, other threads:[~1998-01-15 16:06 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
1998-01-12 20:31 Static members in templates in egcs-1.0.1 Erik Corry
1998-01-14  0:45 ` Lassi A. Tuura
1998-01-14  4:17 ` Mark Mitchell
1998-01-14 23:17   ` Joe Buck
1998-01-14 23:17   ` dave madden
1998-01-15 16:06     ` Joe Buck
1998-01-15 16:06     ` Mark Mitchell
1998-01-14  4:17 ` Joe Buck
1998-01-14  4:17   ` Erik Corry

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