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