public inbox for gcc@gcc.gnu.org
 help / color / mirror / Atom feed
* Re: #pragma interface && generating virtual tables (of templates?)
@ 1999-02-22 13:30 Mike Stump
       [not found] ` < 199902222130.NAA00669@kankakee.wrs.com >
  1999-02-28 22:53 ` Mike Stump
  0 siblings, 2 replies; 12+ messages in thread
From: Mike Stump @ 1999-02-22 13:30 UTC (permalink / raw)
  To: carlo, martin; +Cc: egcs

> From: Carlo Wood <carlo@runaway.xs4all.nl>
> Date: Sun, 21 Feb 1999 02:46:18 +0100 (CET)

> I deleted all occurances of #pragma interface from my 41 headers,
> and the result is:

> 		   Compile time         Size of resulting
> 		   on my PPro200        shared library
> 		   ---------------------------------------
> With #pragma       86 s                 1649639 bytes
> Without #pragma    86 s                 1663340 bytes

Thanks for the information.  It'd be nice to track down these random
few bytes that were not squeezed out, and squeeze a little more, I
think we should be able to reduce the number to be the same or better,
but we really want a small testcase, or a good explanation to fix it.

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

* Re: #pragma interface && generating virtual tables (of templates?)
       [not found] ` < 199902222130.NAA00669@kankakee.wrs.com >
@ 1999-02-22 15:52   ` Martin v. Loewis
       [not found]     ` < 199902222349.AAA00707@mira.isdn.cs.tu-berlin.de >
  1999-02-28 22:53     ` #pragma interface && generating virtual tables (of templates?) Martin v. Loewis
  0 siblings, 2 replies; 12+ messages in thread
From: Martin v. Loewis @ 1999-02-22 15:52 UTC (permalink / raw)
  To: mrs; +Cc: carlo, egcs

> > With #pragma       86 s                 1649639 bytes
> > Without #pragma    86 s                 1663340 bytes
> 
> Thanks for the information.  It'd be nice to track down these random
> few bytes that were not squeezed out

One source certainly is garbage exception regions. If we have linkonce
functions, they get slots in .gcc_except_table, and .eh_frame. Once
duplicate code is removed, the duplicate slots stay. I don't know
whether this would accound for the 14K; having a section-by-section
comparison would be helpful.

Regards,
Martin

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

* Re: #pragma interface
       [not found]     ` < 199902222349.AAA00707@mira.isdn.cs.tu-berlin.de >
@ 1999-02-23  9:18       ` Carlo Wood
  1999-02-28 22:53         ` Carlo Wood
  0 siblings, 1 reply; 12+ messages in thread
From: Carlo Wood @ 1999-02-23  9:18 UTC (permalink / raw)
  To: Martin v. Loewis; +Cc: egcs

| > > With #pragma       86 s                 1649639 bytes
| > > Without #pragma    86 s                 1663340 bytes
| > 
| > Thanks for the information.  It'd be nice to track down these random
| > few bytes that were not squeezed out
| 
| One source certainly is garbage exception regions. If we have linkonce
| functions, they get slots in .gcc_except_table, and .eh_frame. Once
| duplicate code is removed, the duplicate slots stay. I don't know
| whether this would accound for the 14K; having a section-by-section
| comparison would be helpful.
| 
| Regards,
| Martin

I compile(d) with -fno-exceptions

In an attempt to provide more info, I did remove the "#pragma interface"
every time from exactly ONE header file, and then printed the sizes
of the sections.  The result of that is:

                                  removed #pragma interface
   text    data     bss   total	  from header file:
 354556   10404    3920  368880   sys.h
 353930   10404    3920  368254   demangle.h
 353506   10416    3920  367842   debug.h
 353466   10404    3920  367790   support.h
 353431   10388    3920  367739   debugmalloc.h
 353115   10372    3920  367407   sbll.h
 353019   10404    3920  367343   signals.h
 352927   10404    3920  367251   char2str.h
 352860   10404    3920  367184   buf2str.h
 352773   10404    3920  367097   libr_app.h
 352722   10372    3920  367014   file.h
 352681   10400    3920  367001   dbstreambuf.h
 352676   10404    3920  367000   inet_support.h
 352551   10404    3920  366875   ostream_operators.h
 352490   10404    3920  366814   lockable_auto_ptr.h
 352481   10404    3920  366805   strerrno.h
 352426   10404    3920  366750    -
 352423   10436    3920  366779   llists_crosslink.h
 352388   10404    3920  366712   ffstl.h
 352381   10404    3920  366705   ecbll.h
 352380   10404    3920  366704   bcd2str.h
 352085   10396    3912  366393   ebll.h
 351891   10404    3920  366215   pipe.h
 350215   10340    3908  364463   cbll.h
 348322   10272    3896  362490   expire.h
 347828   10292    3904  362024   crosslink.h
 346193   10156    3864  360213   execve.h

From some header files, it was already removed.
So I added it instead:

                                  added #pragma interface
   text    data     bss   total	  to header file:
 351515   10404    3920  365839   select.h
 351786   10404    3920  366110   iodbbuf_fd.h
 352362   10404    3920  366686   listen_sock.h
 352362   10404    3920  366686   listen_sock_dtct.h
 352426   10404    3920  366750    -
 353303   10436    3920  367659   sock.h
 354257   10464    3928  368649   events.h
 355505   10488    3940  369933   timing.h
 361015   11296    4048  376359   traits.h

Interesting is that the size *grows* 3% by *adding* a "#pragma interface"
just to traits.h :)...

The bad cases however are at the top: The cases in which adding
"#pragma interface" indeed makes the (text) size shrink.

I'd charaterize these "winners" as the ones that are included in the
most source files and/or contain functions that are used the most often.
There is no reason to assume they do something special, except being
used a lot.

"sys.h" for instance is #included in EVERY source file, before ANY
other header file is included (including system header files).

A test file with only '#include "libr/sys.h"' in it, compiled
with -E, and skipping all empty lines and comments gives:

==============================================================================
extern "C" { 
typedef unsigned char __u_char;
typedef unsigned short __u_short;
typedef unsigned int __u_int;
typedef unsigned long __u_long;
typedef unsigned long long int __u_quad_t;
typedef long long int __quad_t;
typedef __quad_t *__qaddr_t;
typedef __u_quad_t __dev_t;		 
typedef __u_int __uid_t;		 
typedef __u_int __gid_t;		 
typedef __u_long __ino_t;		 
typedef __u_int __mode_t;		 
typedef __u_int __nlink_t; 		 
typedef long int __off_t;		 
typedef __quad_t __loff_t;		 
typedef int __pid_t;			 
typedef int __ssize_t;			 
typedef struct
  {
    int __val[2];
  } __fsid_t;				 
typedef int __daddr_t;			 
typedef char *__caddr_t;
typedef long int __time_t;
typedef long int __swblk_t;		 
\f
typedef long int __clock_t;
typedef unsigned long int __fd_mask;
typedef struct
  {
    __fd_mask fds_bits[1024  / (8 * sizeof (__fd_mask)) ];
  } __fd_set;
typedef int __key_t;
typedef unsigned short int __ipc_pid_t;
typedef __u_char u_char;
typedef __u_short u_short;
typedef __u_int u_int;
typedef __u_long u_long;
typedef __quad_t quad_t;
typedef __u_quad_t u_quad_t;
typedef __fsid_t fsid_t;
typedef __dev_t dev_t;
typedef __gid_t gid_t;
typedef __ino_t ino_t;
typedef __mode_t mode_t;
typedef __nlink_t nlink_t;
typedef __off_t off_t;
typedef __loff_t loff_t;
typedef __pid_t pid_t;
typedef __uid_t uid_t;
typedef __ssize_t ssize_t;
typedef __daddr_t daddr_t;
typedef __caddr_t caddr_t;
typedef __key_t key_t;
typedef __time_t time_t;
typedef unsigned int size_t;
typedef unsigned long int ulong;
typedef unsigned short int ushort;
typedef unsigned int uint;
typedef int int8_t __attribute__ ((__mode__ (  __QI__ ))) ;
typedef unsigned int u_int8_t __attribute__ ((__mode__ (  __QI__ ))) ;
typedef int int16_t __attribute__ ((__mode__ (  __HI__ ))) ;
typedef unsigned int u_int16_t __attribute__ ((__mode__ (  __HI__ ))) ;
typedef int int32_t __attribute__ ((__mode__ (  __SI__ ))) ;
typedef unsigned int u_int32_t __attribute__ ((__mode__ (  __SI__ ))) ;
typedef int int64_t __attribute__ ((__mode__ (  __DI__ ))) ;
typedef unsigned int u_int64_t __attribute__ ((__mode__ (  __DI__ ))) ;
typedef int register_t __attribute__ ((__mode__ (__word__)));
struct timespec
  {
    long int tv_sec;		 
    long int tv_nsec;		 
  };
extern "C" { 
struct timeval;
typedef __fd_mask fd_mask;
typedef __fd_set fd_set;
extern int __select  (int __nfds, __fd_set *__readfds,
			  __fd_set *__writefds, __fd_set *__exceptfds,
			  struct timeval *__timeout)  ;
extern int select  (int __nfds, __fd_set *__readfds,
			__fd_set *__writefds, __fd_set *__exceptfds,
			struct timeval *__timeout)  ;
extern int __pselect  (int __nfds, __fd_set *__readfds,
			   __fd_set *__writefds, __fd_set *__exceptfds,
			   struct timespec *__timeout)  ;
extern int pselect  (int __nfds, __fd_set *__readfds,
			 __fd_set *__writefds, __fd_set *__exceptfds,
			 struct timespec *__timeout)  ;
} 
} 
const unsigned int malloc_overhead_c = 0;
typedef int sa_handler_param_type;
static const char rcs_ident_sys_sys_h[] __attribute__ ((unused)) =   "$Id: sys.h,v 1.1.1.1 1998/06/17 16:02:19 carlo Exp $" ; 
==============================================================================

So, a clue could perhaps be that a `typedef' uses space in the text segment?
(In a duplicating way)

Note that all of these typedefs come from system header files that were
included from sys.h.  It surprices me that "#pragma interface" seems to
have influence in this case.  Perhaps I should start to include all my
system headers from own headers, so I can add a "#pragma interface" in
front of it (the system headers do not contain a "#pragma interface" by
themselfs).

If I can provide any other info, please let me know.
Hopefully things get easier once I can release libr (I am waiting for
Qt-2.0 to be released because I want to use its QPL).

After adding "#pragma interface" only in those header files where it
makes the text segment shrink, I could get it as small as:

   text    data     bss     dec     hex filename
 329351    9680    3780  342811   53b1b ../../lib/libr.so.0.2.5

which is 10% smaller than the worsed case...

Regard,

 Carlo Wood  <carlo@runaway.xs4all.nl>

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

* Re: #pragma interface
  1999-02-23  9:18       ` #pragma interface Carlo Wood
@ 1999-02-28 22:53         ` Carlo Wood
  0 siblings, 0 replies; 12+ messages in thread
From: Carlo Wood @ 1999-02-28 22:53 UTC (permalink / raw)
  To: Martin v. Loewis; +Cc: egcs

| > > With #pragma       86 s                 1649639 bytes
| > > Without #pragma    86 s                 1663340 bytes
| > 
| > Thanks for the information.  It'd be nice to track down these random
| > few bytes that were not squeezed out
| 
| One source certainly is garbage exception regions. If we have linkonce
| functions, they get slots in .gcc_except_table, and .eh_frame. Once
| duplicate code is removed, the duplicate slots stay. I don't know
| whether this would accound for the 14K; having a section-by-section
| comparison would be helpful.
| 
| Regards,
| Martin

I compile(d) with -fno-exceptions

In an attempt to provide more info, I did remove the "#pragma interface"
every time from exactly ONE header file, and then printed the sizes
of the sections.  The result of that is:

                                  removed #pragma interface
   text    data     bss   total	  from header file:
 354556   10404    3920  368880   sys.h
 353930   10404    3920  368254   demangle.h
 353506   10416    3920  367842   debug.h
 353466   10404    3920  367790   support.h
 353431   10388    3920  367739   debugmalloc.h
 353115   10372    3920  367407   sbll.h
 353019   10404    3920  367343   signals.h
 352927   10404    3920  367251   char2str.h
 352860   10404    3920  367184   buf2str.h
 352773   10404    3920  367097   libr_app.h
 352722   10372    3920  367014   file.h
 352681   10400    3920  367001   dbstreambuf.h
 352676   10404    3920  367000   inet_support.h
 352551   10404    3920  366875   ostream_operators.h
 352490   10404    3920  366814   lockable_auto_ptr.h
 352481   10404    3920  366805   strerrno.h
 352426   10404    3920  366750    -
 352423   10436    3920  366779   llists_crosslink.h
 352388   10404    3920  366712   ffstl.h
 352381   10404    3920  366705   ecbll.h
 352380   10404    3920  366704   bcd2str.h
 352085   10396    3912  366393   ebll.h
 351891   10404    3920  366215   pipe.h
 350215   10340    3908  364463   cbll.h
 348322   10272    3896  362490   expire.h
 347828   10292    3904  362024   crosslink.h
 346193   10156    3864  360213   execve.h

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

* Re: #pragma interface && generating virtual tables (of templates?)
  1999-02-22 13:30 #pragma interface && generating virtual tables (of templates?) Mike Stump
       [not found] ` < 199902222130.NAA00669@kankakee.wrs.com >
@ 1999-02-28 22:53 ` Mike Stump
  1 sibling, 0 replies; 12+ messages in thread
From: Mike Stump @ 1999-02-28 22:53 UTC (permalink / raw)
  To: carlo, martin; +Cc: egcs

> From: Carlo Wood <carlo@runaway.xs4all.nl>
> Date: Sun, 21 Feb 1999 02:46:18 +0100 (CET)

> I deleted all occurances of #pragma interface from my 41 headers,
> and the result is:

> 		   Compile time         Size of resulting
> 		   on my PPro200        shared library
> 		   ---------------------------------------
> With #pragma       86 s                 1649639 bytes
> Without #pragma    86 s                 1663340 bytes

Thanks for the information.  It'd be nice to track down these random
few bytes that were not squeezed out, and squeeze a little more, I
think we should be able to reduce the number to be the same or better,
but we really want a small testcase, or a good explanation to fix it.

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

* Re: #pragma interface && generating virtual tables (of templates?)
  1999-02-22 15:52   ` Martin v. Loewis
       [not found]     ` < 199902222349.AAA00707@mira.isdn.cs.tu-berlin.de >
@ 1999-02-28 22:53     ` Martin v. Loewis
  1 sibling, 0 replies; 12+ messages in thread
From: Martin v. Loewis @ 1999-02-28 22:53 UTC (permalink / raw)
  To: mrs; +Cc: carlo, egcs

> > With #pragma       86 s                 1649639 bytes
> > Without #pragma    86 s                 1663340 bytes
> 
> Thanks for the information.  It'd be nice to track down these random
> few bytes that were not squeezed out

One source certainly is garbage exception regions. If we have linkonce
functions, they get slots in .gcc_except_table, and .eh_frame. Once
duplicate code is removed, the duplicate slots stay. I don't know
whether this would accound for the 14K; having a section-by-section
comparison would be helpful.

Regards,
Martin

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

* Re: #pragma interface && generating virtual tables (of templates?)
  1999-02-20 11:35   ` Martin v. Loewis
       [not found]     ` < 199902201932.UAA03305@mira.isdn.cs.tu-berlin.de >
@ 1999-02-28 22:53     ` Martin v. Loewis
  1 sibling, 0 replies; 12+ messages in thread
From: Martin v. Loewis @ 1999-02-28 22:53 UTC (permalink / raw)
  To: carlo; +Cc: egcs

> /home/carlo/c++/egcs.bugs/bug3/ircd.lag.cc:34: undefined reference to `server_sock_dct virtual table'
[...]
> Am I correct to think that this would be a bug, because
> templates should not be influenced by '#pragma interface'
> at all (since they don't generate code by themselfs to
> begin with)?

I'd agree this is a bug, at least on the information you provided. Of
course, providing a full bug support (i.e. including preprocessor
output of ircd.lag.ii) shouldn't be that difficult, unless you've
copyright problems.

The virtual table for server_sock_dct should get emitted into
ircd.lag.o. As a work-around, you can probably force this by 
implementing get_output_stream out-of-line.

> I understand this is all pretty vague :(, because I can't provide
> a working example - but perhaps someone can give me a clue on
> whether or not using #pragma interface is deprecated in this case
> and/or if I can organize things differently so I won't get undefined
> virtual tables all the time :)

I'd say #pragma interface is deprecated, period. If you count the
trouble you had with it, don't you agree that it wasn't worth it?
With the new weak and link-once symbols on Linux-ELF, there is hardly
any use for it anymore.

Regards,
Martin

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

* #pragma interface && generating virtual tables (of templates?)
  1999-02-20 10:38 Carlo Wood
       [not found] ` < 199902201741.SAA11876@jolan.ppro >
@ 1999-02-28 22:53 ` Carlo Wood
  1 sibling, 0 replies; 12+ messages in thread
From: Carlo Wood @ 1999-02-28 22:53 UTC (permalink / raw)
  To: egcs

Hi all,

I have good reasons to believe that #pragma interface, when
added to a header file which contains templates, results
sometimes (constistently, but too complex for me to understand
under what kind of conditions) in certain virtual tables
not to be generated.

Am I correct to think that this would be a bug, because
templates should not be influenced by '#pragma interface'
at all (since they don't generate code by themselfs to
begin with)?

One of the reasons that I think that this must be a bug
in egcs (I still use 1.1.1 release) is that when I *remove*
a fucntion call somewhere it started to link, see
example below - I can't provide a working example because
of the included header files :(.

If one NOT #defines FOOBAR then the code below compiles and
links fine, if you do #define FOOBAR, then I get
(among other undefines):

/home/carlo/c++/egcs.bugs/bug3/ircd.lag.cc:34: undefined reference to `server_sock_dct virtual table'

The problem is also solved by removing the "#pragma interface"
in one of the header files (libr/sock.h).

When excluding the code between #ifdef FOOBAR ... #endif, it compiles
and links fine, as I just said, and I get:

~/c++/egcs.bugs/bug3>nm -C ircd.lag.o | grep server_sock_dct
00000000 W server_sock_dct::~server_sock_dct(void)
00000000 W server_sock_dct::server_sock_dct(int)
00000000 W server_sock_dct type_info function
00000000 W virtual function thunk (delta:-44) for server_sock_dct::~server_sock_dct(void)
00000000 W virtual function thunk (delta:-64) for server_sock_dct::~server_sock_dct(void)
00000010 C server_sock_dct type_info node
00000000 W server_sock_dct virtual table
00000000 W server_sock_dct::ios virtual table
00000000 W server_sock_dct::fd_dct virtual table
00000000 W server_sock_dct::dbbuf_fd_dtct<write_ostream_ct> virtual table
00000000 W server_sock_dct::get_output_stream(void) const

So, by NOT including the call to timer(), it DOES generate code which
it does not generate when I do NOT call timer():

~/c++/egcs.bugs/bug3>nm -C ircd.lag.o | grep server_sock_dct
00000000 W server_sock_dct::server_sock_dct(int)
         U server_sock_dct virtual table
         U server_sock_dct::ios virtual table
         U server_sock_dct::fd_dct virtual table
         U server_sock_dct::dbbuf_fd_dtct<write_ostream_ct> virtual table

Now normally I'd expect that by calling extra code, extra templates
get instantiated (at most), and not that I get LESS generated code.

I understand this is all pretty vague :(, because I can't provide
a working example - but perhaps someone can give me a clue on
whether or not using #pragma interface is deprecated in this case
and/or if I can organize things differently so I won't get undefined
virtual tables all the time :)... Some general story thus.

At the bottom have added some brainstorming :/

Thanks,

-- 
 Carlo Wood  <carlo@runaway.xs4all.nl>

-----------------------------------------------------------------------------
#include <libr/sys.h>
#include <libr/sock.h>
#include <libr/timing.h>

class server_input_ct : public decode_input_ct {
protected:
  void decode(char *msg, size_t len);
  virtual ostream &get_output_stream(void) const = 0;
  server_input_ct(dbstreambuf_ct *ibuf) : decode_input_ct(ibuf) { }

private:
  void msg_expired(const timer_event_type_ct &expired_at);
};

void server_input_ct::decode(char *msg, size_t len)
{
#ifdef FOOBAR
  struct timeval timeout = { 1, 0 };
  timer(timeout, *this, &msg_expired);
#endif
}

void server_input_ct::msg_expired(const timer_event_type_ct &expired_at)
{
}

class server_sock_dct : public sock_dtct<server_input_ct, write_ostream_ct> {
protected:
  virtual ostream &get_output_stream(void) const { return *((ostream *)NULL); }
};

int main(void)
{
  new server_sock_dct();
}
==============================================================================

More about the header files:

The reason for class server_sock_dct not to be generated (its virtual table
that is) can probably found in the fact that:

/home/carlo/c++/egcs.bugs/bug3/ircd.lag.cc:34: undefined reference to `server_sock_dct::dbbuf_fd_dtct<write_ostream_ct> virtual table'

The hierarchy of the classes is:

class server_sock_dct :
    public sock_dtct<server_input_ct, write_ostream_ct>

sock_dtct<server_input_ct, write_ostream_ct> :
    public iodbbuf_fd_dtct<server_input_ct, write_ostream_ct>, private sockbuf_dbct, virtual public fd_dct

class sockbuf_dbct : virtual public fd_dct

class fd_dct : public node_tct<sbll_node_ct, fd_dct>

class node_tct<sbll_node_ct, fd_dct> : public sbll_node_ct

class sbll_node_ct: private sbll_base_ct

class sbll_base_ct

class iodbbuf_fd_dtct<server_input_ct, write_ostream_ct> :
    public dbbuf_fd_dtct<server_input_ct>, public dbbuf_fd_dtct<write_ostream_ct>, virtual public fd_dct

class server_input_ct : public decode_input_ct

class decode_input_ct : public line_input_ct

class line_input_ct : public read_input_ct

class read_input_ct : public input_ct

class input_ct : virtual public fd_dct

class write_ostream_ct : public write_output_ct, public ostream

class write_output_ct : public output_ct

class output_ct : virtual public fd_dct

class dbbuf_fd_dtct<server_input_ct> : public server_input_ct, virtual public fd_dct

class dbbuf_fd_dtct<write_ostream_ct> : public write_ostream_ct, virtual public fd_dct

(This makes clear I hope why I can't seem to make a small working example).

In other words, when dbbuf_fd_dtct<write_ostream_ct> virtual table
is not generated, then iodbbuf_fd_dtct<server_input_ct, write_ostream_ct> virtual table
is not generated, then sock_dtct<server_input_ct, write_ostream_ct> virtual table
is not generated, then server_sock_dct virtual table is not generated.

There doesn't seem any reason however why dbbuf_fd_dtct<write_ostream_ct> virtual table
is not generated: This class is only derived from write_ostream_ct and
the virtual base class fd_dct - which both are stable classes that have worked
for at least a year now.

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

* Re: #pragma interface && generating virtual tables (of templates?)
  1999-02-20 20:38       ` Carlo Wood
@ 1999-02-28 22:53         ` Carlo Wood
  0 siblings, 0 replies; 12+ messages in thread
From: Carlo Wood @ 1999-02-28 22:53 UTC (permalink / raw)
  To: Martin v. Loewis; +Cc: egcs

| I'd say #pragma interface is deprecated, period. If you count the
| trouble you had with it, don't you agree that it wasn't worth it?

It used to be worth it.

| With the new weak and link-once symbols on Linux-ELF, there is hardly
| any use for it anymore.
| 
| Regards,
| Martin

Thank you :).

I deleted all occurances of #pragma interface from my 41 headers,
and the result is:

		   Compile time         Size of resulting
		   on my PPro200        shared library
		   ---------------------------------------
With #pragma       86 s                 1649639 bytes
Without #pragma    86 s                 1663340 bytes

I guess I'll stop using it.

-- 
 Carlo Wood  <carlo@runaway.xs4all.nl>

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

* Re: #pragma interface && generating virtual tables (of templates?)
       [not found]     ` < 199902201932.UAA03305@mira.isdn.cs.tu-berlin.de >
@ 1999-02-20 20:38       ` Carlo Wood
  1999-02-28 22:53         ` Carlo Wood
  0 siblings, 1 reply; 12+ messages in thread
From: Carlo Wood @ 1999-02-20 20:38 UTC (permalink / raw)
  To: Martin v. Loewis; +Cc: egcs

| I'd say #pragma interface is deprecated, period. If you count the
| trouble you had with it, don't you agree that it wasn't worth it?

It used to be worth it.

| With the new weak and link-once symbols on Linux-ELF, there is hardly
| any use for it anymore.
| 
| Regards,
| Martin

Thank you :).

I deleted all occurances of #pragma interface from my 41 headers,
and the result is:

		   Compile time         Size of resulting
		   on my PPro200        shared library
		   ---------------------------------------
With #pragma       86 s                 1649639 bytes
Without #pragma    86 s                 1663340 bytes

I guess I'll stop using it.

-- 
 Carlo Wood  <carlo@runaway.xs4all.nl>

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

* Re: #pragma interface && generating virtual tables (of templates?)
       [not found] ` < 199902201741.SAA11876@jolan.ppro >
@ 1999-02-20 11:35   ` Martin v. Loewis
       [not found]     ` < 199902201932.UAA03305@mira.isdn.cs.tu-berlin.de >
  1999-02-28 22:53     ` Martin v. Loewis
  0 siblings, 2 replies; 12+ messages in thread
From: Martin v. Loewis @ 1999-02-20 11:35 UTC (permalink / raw)
  To: carlo; +Cc: egcs

> /home/carlo/c++/egcs.bugs/bug3/ircd.lag.cc:34: undefined reference to `server_sock_dct virtual table'
[...]
> Am I correct to think that this would be a bug, because
> templates should not be influenced by '#pragma interface'
> at all (since they don't generate code by themselfs to
> begin with)?

I'd agree this is a bug, at least on the information you provided. Of
course, providing a full bug support (i.e. including preprocessor
output of ircd.lag.ii) shouldn't be that difficult, unless you've
copyright problems.

The virtual table for server_sock_dct should get emitted into
ircd.lag.o. As a work-around, you can probably force this by 
implementing get_output_stream out-of-line.

> I understand this is all pretty vague :(, because I can't provide
> a working example - but perhaps someone can give me a clue on
> whether or not using #pragma interface is deprecated in this case
> and/or if I can organize things differently so I won't get undefined
> virtual tables all the time :)

I'd say #pragma interface is deprecated, period. If you count the
trouble you had with it, don't you agree that it wasn't worth it?
With the new weak and link-once symbols on Linux-ELF, there is hardly
any use for it anymore.

Regards,
Martin

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

* #pragma interface && generating virtual tables (of templates?)
@ 1999-02-20 10:38 Carlo Wood
       [not found] ` < 199902201741.SAA11876@jolan.ppro >
  1999-02-28 22:53 ` Carlo Wood
  0 siblings, 2 replies; 12+ messages in thread
From: Carlo Wood @ 1999-02-20 10:38 UTC (permalink / raw)
  To: egcs

Hi all,

I have good reasons to believe that #pragma interface, when
added to a header file which contains templates, results
sometimes (constistently, but too complex for me to understand
under what kind of conditions) in certain virtual tables
not to be generated.

Am I correct to think that this would be a bug, because
templates should not be influenced by '#pragma interface'
at all (since they don't generate code by themselfs to
begin with)?

One of the reasons that I think that this must be a bug
in egcs (I still use 1.1.1 release) is that when I *remove*
a fucntion call somewhere it started to link, see
example below - I can't provide a working example because
of the included header files :(.

If one NOT #defines FOOBAR then the code below compiles and
links fine, if you do #define FOOBAR, then I get
(among other undefines):

/home/carlo/c++/egcs.bugs/bug3/ircd.lag.cc:34: undefined reference to `server_sock_dct virtual table'

The problem is also solved by removing the "#pragma interface"
in one of the header files (libr/sock.h).

When excluding the code between #ifdef FOOBAR ... #endif, it compiles
and links fine, as I just said, and I get:

~/c++/egcs.bugs/bug3>nm -C ircd.lag.o | grep server_sock_dct
00000000 W server_sock_dct::~server_sock_dct(void)
00000000 W server_sock_dct::server_sock_dct(int)
00000000 W server_sock_dct type_info function
00000000 W virtual function thunk (delta:-44) for server_sock_dct::~server_sock_dct(void)
00000000 W virtual function thunk (delta:-64) for server_sock_dct::~server_sock_dct(void)
00000010 C server_sock_dct type_info node
00000000 W server_sock_dct virtual table
00000000 W server_sock_dct::ios virtual table
00000000 W server_sock_dct::fd_dct virtual table
00000000 W server_sock_dct::dbbuf_fd_dtct<write_ostream_ct> virtual table
00000000 W server_sock_dct::get_output_stream(void) const

So, by NOT including the call to timer(), it DOES generate code which
it does not generate when I do NOT call timer():

~/c++/egcs.bugs/bug3>nm -C ircd.lag.o | grep server_sock_dct
00000000 W server_sock_dct::server_sock_dct(int)
         U server_sock_dct virtual table
         U server_sock_dct::ios virtual table
         U server_sock_dct::fd_dct virtual table
         U server_sock_dct::dbbuf_fd_dtct<write_ostream_ct> virtual table

Now normally I'd expect that by calling extra code, extra templates
get instantiated (at most), and not that I get LESS generated code.

I understand this is all pretty vague :(, because I can't provide
a working example - but perhaps someone can give me a clue on
whether or not using #pragma interface is deprecated in this case
and/or if I can organize things differently so I won't get undefined
virtual tables all the time :)... Some general story thus.

At the bottom have added some brainstorming :/

Thanks,

-- 
 Carlo Wood  <carlo@runaway.xs4all.nl>

-----------------------------------------------------------------------------
#include <libr/sys.h>
#include <libr/sock.h>
#include <libr/timing.h>

class server_input_ct : public decode_input_ct {
protected:
  void decode(char *msg, size_t len);
  virtual ostream &get_output_stream(void) const = 0;
  server_input_ct(dbstreambuf_ct *ibuf) : decode_input_ct(ibuf) { }

private:
  void msg_expired(const timer_event_type_ct &expired_at);
};

void server_input_ct::decode(char *msg, size_t len)
{
#ifdef FOOBAR
  struct timeval timeout = { 1, 0 };
  timer(timeout, *this, &msg_expired);
#endif
}

void server_input_ct::msg_expired(const timer_event_type_ct &expired_at)
{
}

class server_sock_dct : public sock_dtct<server_input_ct, write_ostream_ct> {
protected:
  virtual ostream &get_output_stream(void) const { return *((ostream *)NULL); }
};

int main(void)
{
  new server_sock_dct();
}
==============================================================================

More about the header files:

The reason for class server_sock_dct not to be generated (its virtual table
that is) can probably found in the fact that:

/home/carlo/c++/egcs.bugs/bug3/ircd.lag.cc:34: undefined reference to `server_sock_dct::dbbuf_fd_dtct<write_ostream_ct> virtual table'

The hierarchy of the classes is:

class server_sock_dct :
    public sock_dtct<server_input_ct, write_ostream_ct>

sock_dtct<server_input_ct, write_ostream_ct> :
    public iodbbuf_fd_dtct<server_input_ct, write_ostream_ct>, private sockbuf_dbct, virtual public fd_dct

class sockbuf_dbct : virtual public fd_dct

class fd_dct : public node_tct<sbll_node_ct, fd_dct>

class node_tct<sbll_node_ct, fd_dct> : public sbll_node_ct

class sbll_node_ct: private sbll_base_ct

class sbll_base_ct

class iodbbuf_fd_dtct<server_input_ct, write_ostream_ct> :
    public dbbuf_fd_dtct<server_input_ct>, public dbbuf_fd_dtct<write_ostream_ct>, virtual public fd_dct

class server_input_ct : public decode_input_ct

class decode_input_ct : public line_input_ct

class line_input_ct : public read_input_ct

class read_input_ct : public input_ct

class input_ct : virtual public fd_dct

class write_ostream_ct : public write_output_ct, public ostream

class write_output_ct : public output_ct

class output_ct : virtual public fd_dct

class dbbuf_fd_dtct<server_input_ct> : public server_input_ct, virtual public fd_dct

class dbbuf_fd_dtct<write_ostream_ct> : public write_ostream_ct, virtual public fd_dct

(This makes clear I hope why I can't seem to make a small working example).

In other words, when dbbuf_fd_dtct<write_ostream_ct> virtual table
is not generated, then iodbbuf_fd_dtct<server_input_ct, write_ostream_ct> virtual table
is not generated, then sock_dtct<server_input_ct, write_ostream_ct> virtual table
is not generated, then server_sock_dct virtual table is not generated.

There doesn't seem any reason however why dbbuf_fd_dtct<write_ostream_ct> virtual table
is not generated: This class is only derived from write_ostream_ct and
the virtual base class fd_dct - which both are stable classes that have worked
for at least a year now.

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

end of thread, other threads:[~1999-02-28 22:53 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
1999-02-22 13:30 #pragma interface && generating virtual tables (of templates?) Mike Stump
     [not found] ` < 199902222130.NAA00669@kankakee.wrs.com >
1999-02-22 15:52   ` Martin v. Loewis
     [not found]     ` < 199902222349.AAA00707@mira.isdn.cs.tu-berlin.de >
1999-02-23  9:18       ` #pragma interface Carlo Wood
1999-02-28 22:53         ` Carlo Wood
1999-02-28 22:53     ` #pragma interface && generating virtual tables (of templates?) Martin v. Loewis
1999-02-28 22:53 ` Mike Stump
  -- strict thread matches above, loose matches on Subject: below --
1999-02-20 10:38 Carlo Wood
     [not found] ` < 199902201741.SAA11876@jolan.ppro >
1999-02-20 11:35   ` Martin v. Loewis
     [not found]     ` < 199902201932.UAA03305@mira.isdn.cs.tu-berlin.de >
1999-02-20 20:38       ` Carlo Wood
1999-02-28 22:53         ` Carlo Wood
1999-02-28 22:53     ` Martin v. Loewis
1999-02-28 22:53 ` Carlo Wood

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