public inbox for gcc@gcc.gnu.org
 help / color / mirror / Atom feed
* Re: C++ and static data members...
@ 1999-09-03 12:37 David_Abrahams
  1999-09-30 18:02 ` David_Abrahams
  0 siblings, 1 reply; 22+ messages in thread
From: David_Abrahams @ 1999-09-03 12:37 UTC (permalink / raw)
  To: gcc

Joe Buck writ:

>No, the purpose of a standard is to standardize existing practice, not
>to introduce new stuff that's never been seen before unless it fills
>a vital need.

This is often stated exactly in the manner above, as an absolute truth. It is
not, however, true at all in the case of C++. The issue of whether
standardization should go beyond codifying existing practice has (as you might
imagine) come up often in the C++ committee. Many people believe it should be
the aim of the committee to simply codify existing practice, but inevitably
someone will cite the committee charter which makes no attempt to limit the
effort's scope in this way. All the same, nobody on the committee (to my
knowledge) thinks it is appropriate to wantonly violate or ignore existing
practice.

>You seem to want g++ to ignore all existing practice
>and include any .o file that has a static object with a constructor.
>This would be a disaster; executable sizes would bloat, and programs
>that depend on the existing behavior would break.

If I understand the proposal I think you can find a good argument against it in
std::cout. This object is potentially initialized in every translation unit that
includes <iostream> through the use of a proxy which is actually constructed in
each unit.

3.6.2/3 allows a compiler to defer initialization of a static object until its
first use, which in the case of code that never uses cout... is never. With many
linker implementations, if the initialization gets linked in, so does everything
else in the translation unit.

It is legitimate to have a compiler option which turns this deferring behavior
off. The Metrowerks compiler, for example, includes such a switch. Still, you
should expect larger executables if you exercise that option.

-Dave


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

* Re: C++ and static data members...
  1999-09-03 12:37 C++ and static data members David_Abrahams
@ 1999-09-30 18:02 ` David_Abrahams
  0 siblings, 0 replies; 22+ messages in thread
From: David_Abrahams @ 1999-09-30 18:02 UTC (permalink / raw)
  To: gcc

Joe Buck writ:

>No, the purpose of a standard is to standardize existing practice, not
>to introduce new stuff that's never been seen before unless it fills
>a vital need.

This is often stated exactly in the manner above, as an absolute truth. It is
not, however, true at all in the case of C++. The issue of whether
standardization should go beyond codifying existing practice has (as you might
imagine) come up often in the C++ committee. Many people believe it should be
the aim of the committee to simply codify existing practice, but inevitably
someone will cite the committee charter which makes no attempt to limit the
effort's scope in this way. All the same, nobody on the committee (to my
knowledge) thinks it is appropriate to wantonly violate or ignore existing
practice.

>You seem to want g++ to ignore all existing practice
>and include any .o file that has a static object with a constructor.
>This would be a disaster; executable sizes would bloat, and programs
>that depend on the existing behavior would break.

If I understand the proposal I think you can find a good argument against it in
std::cout. This object is potentially initialized in every translation unit that
includes <iostream> through the use of a proxy which is actually constructed in
each unit.

3.6.2/3 allows a compiler to defer initialization of a static object until its
first use, which in the case of code that never uses cout... is never. With many
linker implementations, if the initialization gets linked in, so does everything
else in the translation unit.

It is legitimate to have a compiler option which turns this deferring behavior
off. The Metrowerks compiler, for example, includes such a switch. Still, you
should expect larger executables if you exercise that option.

-Dave


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

* Re: C++ and static data members...
  1999-09-02 16:41 ` Joe Buck
@ 1999-09-30 18:02   ` Joe Buck
  0 siblings, 0 replies; 22+ messages in thread
From: Joe Buck @ 1999-09-30 18:02 UTC (permalink / raw)
  To: Theodore Papadopoulo; +Cc: gcc

> The C++ standard explicitly states that:
> 3.7.1 2 If an object of static storage has initialization or 
> destructor with side effects, it shall not be eliminated even if it 
> appears to be unused, except that a class object or its copy may be 
> eliminated as specified in 12.8

Right, once the static object is included it may not be eliminated.
But we do not, by default, include all code that appears in a library.
(If the rule required that, then it would be impossible to implement
C++ using a standard Unix/Posix linker).  .o files are only sucked in
from libraries for the purpose of satisfying global symbol definitions.

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

* C++ and static data members...
  1999-09-02 15:52 Theodore Papadopoulo
  1999-09-02 16:27 ` Martin v. Loewis
  1999-09-02 16:41 ` Joe Buck
@ 1999-09-30 18:02 ` Theodore Papadopoulo
  2 siblings, 0 replies; 22+ messages in thread
From: Theodore Papadopoulo @ 1999-09-30 18:02 UTC (permalink / raw)
  To: gcc

The C++ standard explicitly states that:
3.7.1 2 If an object of static storage has initialization or 
destructor with side effects, it shall not be eliminated even if it 
appears to be unused, except that a class object or its copy may be 
eliminated as specified in 12.8

I'm quite puzzled by the behaviour of the compiler (well actually the
linker) for the small program given below. I'm certainly missing 
something.... HUGE but I cannot figure out what. This is all the more 
annoying that I'm using this kind of construction in many libraries 
(I just wonder why I have not been struck by this before).

The example is done with:

mururoa->g++ -v
Reading specs from /usr/local/gcc/lib/gcc-lib/sparc-sun-solaris2.6/2.95.1/specs
gcc version 2.95.1 19990816 (release)

But the thing same happens with:

ouahu->g++ -v
Reading specs from /usr/local/gcc/lib/gcc-lib/i686-pc-linux-gnu/2.95.1/specs
gcc version 2.95.1 19990816 (release)

So its maybe an ELF specific problem but seems not a Solaris ld/gnu ld one...

mururoa->cat A.H
#include <stdio.h>
#include <iostream.h>

class A {
public:

        static void f() { cout << "I was here" << endl; }

private:

        A() { fprintf(stderr,"Constructing A\n"); }

        static const A proto;
};
// End of A.H

mururoa->cat A.C
#include "A.H"

const A A::proto;
// End of A.H

mururoa->g++ -c A.C 
mururoa->ar r libA.a A.o
ar: creating libA.a

mururoa->cat Main.C 
#include "A.H"

int
main()
{
        A::f();
}
// End of Main.C

mururoa->g++ Main.C -L. -lA
mururoa->./a.out 
I was here

The constructor for the static copy is never called!
And indeed nm shows that no code is linked for class A::A(void).

mururoa->g++ Main.C A.o
mururoa->./a.out
Constructing A
I was here

This one works as expected...

nm shows:
[484] |    256896|       1|OBJT |GLOB |0    |97     |A::proto
[128] |    108816|      32|FUNC |LOCL |0    |9      |global constructors keyed to A::proto
[725] |    169540|      52|FUNC |WEAK |0    |13     |A::A(void)

that were no present in the previous case.

 --------------------------------------------------------------------
 Theodore Papadopoulo
 Email: Theodore.Papadopoulo@sophia.inria.fr Tel: (33) 04 92 38 76 01
 --------------------------------------------------------------------



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

* Re: C++ and static data members...
  1999-09-03 20:33     ` Alexandre Oliva
@ 1999-09-30 18:02       ` Alexandre Oliva
  0 siblings, 0 replies; 22+ messages in thread
From: Alexandre Oliva @ 1999-09-30 18:02 UTC (permalink / raw)
  To: Theodore Papadopoulo; +Cc: Joe Buck, gcc, martin

On Sep  3, 1999, Theodore Papadopoulo <Theodore.Papadopoulo@sophia.inria.fr> wrote:

> First, let me be clear. I do not want a new feature. I just find the current 
> behaviour strange and non-natural from the programmer's view. If there is no 
> way to improve that at small cost, too bad...

But there is: don't define the static function inline; define it in
the implementation file only.  This will make sure the object file in
the library will be sucked in, bringing with it the static
initializers.

> Boy, I wanted to learn how to use libtool, it is an occasion...

Please note that libtool doesn't support any language other than C
yet, although it does work with g++, by luck, on a couple of
platforms.

-- 
Alexandre Oliva http://www.dcc.unicamp.br/~oliva IC-Unicamp, Bra[sz]il
oliva@{dcc.unicamp.br,guarana.{org,com}} aoliva@{acm.org,computer.org}
oliva@{gnu.org,kaffe.org,{egcs,sourceware}.cygnus.com,samba.org}
** I may forward mail about projects to mailing lists; please use them

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

* Re: C++ and static data members...
  1999-09-02 16:27 ` Martin v. Loewis
  1999-09-02 16:36   ` Joe Buck
@ 1999-09-30 18:02   ` Martin v. Loewis
  1 sibling, 0 replies; 22+ messages in thread
From: Martin v. Loewis @ 1999-09-30 18:02 UTC (permalink / raw)
  To: Theodore.Papadopoulo; +Cc: gcc

> I'm quite puzzled by the behaviour of the compiler (well actually the
> linker) for the small program given below. I'm certainly missing 
> something.... HUGE but I cannot figure out what.

Well, you are missing an implementation restriction. You must not put
the object files containing such globals in a library. Instead, you
must pass them to the linking command line explicitly.

This is because of the way the linker works: it won't use object files
from a library unless they are used.

If you absolutely want to use the library, and use are using GNU ld, you
can say

g++ -o a Main.C -L. -Wl,--whole-archive -lA -Wl,--no-whole-archive

That will use the entire library, including all static objects which
are not referenced otherwise.

Please note that this is not in violation of the C++ standard, since
object file archives are not known to the standard.

Regards,
Martin

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

* Re: C++ and static data members...
  1999-09-03 12:29   ` Joern Rennecke
@ 1999-09-30 18:02     ` Joern Rennecke
  0 siblings, 0 replies; 22+ messages in thread
From: Joern Rennecke @ 1999-09-30 18:02 UTC (permalink / raw)
  To: Joe Buck; +Cc: Theodore.Papadopoulo, gcc, martin, jbuck

> You always have the option of specifying the .o files you want explicitly
> on the linker command line.

Or easier to use in practive if you already have a library: just
tell the linker to start out with a global symbol from the wanted .o file
marked as undefined (i.e. the -u option of gnu ld).

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

* Re: C++ and static data members...
  1999-09-03 10:13 Theodore Papadopoulo
  1999-09-03 10:25 ` Joe Buck
  1999-09-06 14:40 ` Martin v. Loewis
@ 1999-09-30 18:02 ` Theodore Papadopoulo
  2 siblings, 0 replies; 22+ messages in thread
From: Theodore Papadopoulo @ 1999-09-30 18:02 UTC (permalink / raw)
  To: gcc; +Cc: Martin v. Loewis, Joe Buck

martin@mira.isdn.cs.tu-berlin.de said:
> Well, you are missing an implementation restriction. You must not put
> the object files containing such globals in a library. Instead, you
> must pass them to the linking command line explicitly. 

jbuck@synopsys.com said:
> That last sentence is not very clear.  What actually happens is that
> the linker processes files and libraries on the command line left to
> right. It will not select an object file from a library unless that
> object file defines a global symbol that is currently undefined.  To
> oversimplify things a bit, initially only the symbol "main" is
> undefined (really it's a bit different: a startup function is chosen
> which calls main, but it gives you a picture of what's going on).

> If you want to be sure that a particular static object is included,
> you can make sure that the .o file that contains it also defines some
> global symbol that is referenced by some other file that must be
> included. 

Yes, I realized that. Anyway, thank's for the explanation and the tricks. 
It remains the fact that for C++ this can seem very weird.
I cannot think of the same kind of problem arising with C.

martin@mira.isdn.cs.tu-berlin.de said:
> Please note that this is not in violation of the C++ standard, since
> object file archives are not known to the standard. 

I was expecting such an answer... It seems also a little too simple 
answer as I'm sure that the standard indeed makes implicitly 
use of quite some knowledge of the object and linking technology, but 
let's not discuss that.

However, your wording seems to mean that's a quality of 
implementation issue (this is the right term to use when dealing with 
letter vs spirit of the standard issues right?) since it seems that
the behaviour of the compiling system (as opposed to the compiler itself)
is undefined in the current state. Am I right, or is the current behaviour
mandated somehow ?

If it is indeed a quality of implementation issue, then would it be
accepted to add something to correct this in g++ ?

In my naive view, it should not be extremely difficult to add references
to the static variables (only those that have a side effect if gcc can detect that)
in a special section (as for the exception handling info) named eg .always_link
at compile time and use collect2 to generate a .o file that names those variables and 
that would be inserted in the link line before the library.
Of course this is very ELF specific. There should be other ways 
to mark and detect the relevant variables (name mangling ??).
I do not know which method is the best but this seems feasible...

If this (or a variation of it) is acceptable, then I might try to do it 
(I might need of a little help however).

	Thank's for your audience,

	Theo.
 

 --------------------------------------------------------------------
 Theodore Papadopoulo
 Email: Theodore.Papadopoulo@sophia.inria.fr Tel: (33) 04 92 38 76 01
 --------------------------------------------------------------------



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

* Re: C++ and static data members...
  1999-09-06 14:40 ` Martin v. Loewis
@ 1999-09-30 18:02   ` Martin v. Loewis
  0 siblings, 0 replies; 22+ messages in thread
From: Martin v. Loewis @ 1999-09-30 18:02 UTC (permalink / raw)
  To: Theodore.Papadopoulo; +Cc: gcc, jbuck

> Yes, I realized that. Anyway, thank's for the explanation and the tricks. 
> It remains the fact that for C++ this can seem very weird.

Yes, it is definitely a fact: C++ can seem very weird :-)

> However, your wording seems to mean that's a quality of
> implementation issue (this is the right term to use when dealing
> with letter vs spirit of the standard issues right?) since it seems
> that the behaviour of the compiling system (as opposed to the
> compiler itself) is undefined in the current state. Am I right, or
> is the current behaviour mandated somehow ?

I believe you are wrong, here. The current behaviour is at least
mandated by existing practice over the last ten years or so. Perhaps
it is even mandated by the ELF specification, which explains how the
archive files work, what undefined symbols are, and how the linker
operates.

> If it is indeed a quality of implementation issue, then would it be
> accepted to add something to correct this in g++ ?

I guess that depends. Although I tend agree it is a QoI issue, it is
not easy to improve the quality. If you come up with a fix, you'll
probably have to convince *a lot* of people that this is the right
thing to do, and you'll have to take the blame *for years* when people
complain that this was changed. But if it is important to you, you can
try, anyway.

In short: everybody has accepted things as being as they are, and
there is really no serious problem (IMHO), so I personally wouldn't
engage in a project to change this.

Regards,
Martin

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

* Re: C++ and static data members...
  1999-09-03 16:16   ` Theodore Papadopoulo
  1999-09-03 20:33     ` Alexandre Oliva
@ 1999-09-30 18:02     ` Theodore Papadopoulo
  1 sibling, 0 replies; 22+ messages in thread
From: Theodore Papadopoulo @ 1999-09-30 18:02 UTC (permalink / raw)
  To: Joe Buck; +Cc: gcc, martin

First, let me be clear. I do not want a new feature. I just find the current 
behaviour strange and non-natural from the programmer's view. If there is no 
way to improve that at small cost, too bad...

> No, the purpose of a standard is to standardize existing practice, not
> to introduce new stuff that's never been seen before unless it fills
> a vital need.  You seem to want g++ to ignore all existing practice
> and include any .o file that has a static object with a constructor.

Well to most users (with a strong C predjudice, I must agree (but I'm n
ot a C++ beginner either)), if something works compiling a set of .o then
if you put part of your .o into a library and recompile with it instead,
it still works. That's existing practice also...

AFAICT, the static members initialization is the feature that makes
this behaviour to appear, so in some way it is a C++ ``concern'' (I'm 
trying to avoid the word problem).

As is by the way the concern of the order of such initializations across 
translation units. In fine, static members are not so easy to use !!! 
Too bad :-(

> This would be a disaster; executable sizes would bloat, and programs
> that depend on the existing behavior would break.

Size of executables might indeed be a problem. 
I'm not sure to see programs that would rely on such a strange 
behaviour (.o vs .a link properties)... but I have certainly not
seen everything :-)

> (example: use of static constructors to register information about what
> code has been included, or to implement the "object factory" pattern.  If
> this scheme is used, your proposed change would require that every file in
> every library be included in every executable).

The funny thing is that it is exactly what I wanted to do (register various 
file formats readers/writers).... Everything worked well untill I created the library...
I worked around my problem by putting the static variable definitions 
into the file that registers the information. That's a modularity 
disaster but it works fine. It is just more tricky to extend than it should 
have been...

> You always have the option of specifying the .o files you want explicitly
> on the linker command line.

IMHO, offer a library and then ask to people to link with a given .o plus 
the library is a no-no....

Actually, creating a dynamic library instead of a static one is maybe 
the easiest solution from both the implementer and the user point of 
view. Boy, I wanted to learn how to use libtool, it is an 
occasion...

	Thank's anyhow for all your clarifications...


--------------------------------------------------------------------
Theodore Papadopoulo
Email: Theodore.Papadopoulo@sophia.inria.fr Tel: (33) 04 92 38 76 01
 --------------------------------------------------------------------


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

* Re: C++ and static data members...
  1999-09-03 10:25 ` Joe Buck
  1999-09-03 12:29   ` Joern Rennecke
  1999-09-03 16:16   ` Theodore Papadopoulo
@ 1999-09-30 18:02   ` Joe Buck
  2 siblings, 0 replies; 22+ messages in thread
From: Joe Buck @ 1999-09-30 18:02 UTC (permalink / raw)
  To: Theodore Papadopoulo; +Cc: gcc, martin, jbuck

[ static objects in a library may not be defined ]

> martin@mira.isdn.cs.tu-berlin.de said:
> > Please note that this is not in violation of the C++ standard, since
> > object file archives are not known to the standard. 
> 
> I was expecting such an answer... It seems also a little too simple 
> answer as I'm sure that the standard indeed makes implicitly 
> use of quite some knowledge of the object and linking technology, but 
> let's not discuss that.
> 
> However, your wording seems to mean that's a quality of 
> implementation issue (this is the right term to use when dealing with 
> letter vs spirit of the standard issues right?)

No, the purpose of a standard is to standardize existing practice, not
to introduce new stuff that's never been seen before unless it fills
a vital need.  You seem to want g++ to ignore all existing practice
and include any .o file that has a static object with a constructor.
This would be a disaster; executable sizes would bloat, and programs
that depend on the existing behavior would break.

(example: use of static constructors to register information about what
code has been included, or to implement the "object factory" pattern.  If
this scheme is used, your proposed change would require that every file in
every library be included in every executable).

There is no "spirit of the standard" that suggests that what you want
to occur, will occur.  The standard does not talk about files, libraries,
etc.  As far as the standard is concerned, some mechanism outside the
scope of the standard assembles all of the pieces of the program.  It
might be object files and libraries, or it might be a database.  The
passage you originally referred to then talks about what code can be
dropped or not dropped from this collection of pieces.  In this case,
the static objects in question are never part of the program in the
first place.

You always have the option of specifying the .o files you want explicitly
on the linker command line.

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

* Re: C++ and static data members...
  1999-09-02 16:36   ` Joe Buck
@ 1999-09-30 18:02     ` Joe Buck
  0 siblings, 0 replies; 22+ messages in thread
From: Joe Buck @ 1999-09-30 18:02 UTC (permalink / raw)
  To: Martin v. Loewis; +Cc: Theodore.Papadopoulo, gcc

Martin Loewis writes:
> Well, you are missing an implementation restriction. You must not put
> the object files containing such globals in a library. Instead, you
> must pass them to the linking command line explicitly.
> 
> This is because of the way the linker works: it won't use object files
> from a library unless they are used.

That last sentence is not very clear.  What actually happens is that the
linker processes files and libraries on the command line left to right.
It will not select an object file from a library unless that object file
defines a global symbol that is currently undefined.  To oversimplify
things a bit, initially only the symbol "main" is undefined (really
it's a bit different: a startup function is chosen which calls main,
but it gives you a picture of what's going on).

If you want to be sure that a particular static object is included, you
can make sure that the .o file that contains it also defines some global
symbol that is referenced by some other file that must be included.



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

* Re: C++ and static data members...
  1999-09-03 10:13 Theodore Papadopoulo
  1999-09-03 10:25 ` Joe Buck
@ 1999-09-06 14:40 ` Martin v. Loewis
  1999-09-30 18:02   ` Martin v. Loewis
  1999-09-30 18:02 ` Theodore Papadopoulo
  2 siblings, 1 reply; 22+ messages in thread
From: Martin v. Loewis @ 1999-09-06 14:40 UTC (permalink / raw)
  To: Theodore.Papadopoulo; +Cc: gcc, jbuck

> Yes, I realized that. Anyway, thank's for the explanation and the tricks. 
> It remains the fact that for C++ this can seem very weird.

Yes, it is definitely a fact: C++ can seem very weird :-)

> However, your wording seems to mean that's a quality of
> implementation issue (this is the right term to use when dealing
> with letter vs spirit of the standard issues right?) since it seems
> that the behaviour of the compiling system (as opposed to the
> compiler itself) is undefined in the current state. Am I right, or
> is the current behaviour mandated somehow ?

I believe you are wrong, here. The current behaviour is at least
mandated by existing practice over the last ten years or so. Perhaps
it is even mandated by the ELF specification, which explains how the
archive files work, what undefined symbols are, and how the linker
operates.

> If it is indeed a quality of implementation issue, then would it be
> accepted to add something to correct this in g++ ?

I guess that depends. Although I tend agree it is a QoI issue, it is
not easy to improve the quality. If you come up with a fix, you'll
probably have to convince *a lot* of people that this is the right
thing to do, and you'll have to take the blame *for years* when people
complain that this was changed. But if it is important to you, you can
try, anyway.

In short: everybody has accepted things as being as they are, and
there is really no serious problem (IMHO), so I personally wouldn't
engage in a project to change this.

Regards,
Martin

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

* Re: C++ and static data members...
  1999-09-03 16:16   ` Theodore Papadopoulo
@ 1999-09-03 20:33     ` Alexandre Oliva
  1999-09-30 18:02       ` Alexandre Oliva
  1999-09-30 18:02     ` Theodore Papadopoulo
  1 sibling, 1 reply; 22+ messages in thread
From: Alexandre Oliva @ 1999-09-03 20:33 UTC (permalink / raw)
  To: Theodore Papadopoulo; +Cc: Joe Buck, gcc, martin

On Sep  3, 1999, Theodore Papadopoulo <Theodore.Papadopoulo@sophia.inria.fr> wrote:

> First, let me be clear. I do not want a new feature. I just find the current 
> behaviour strange and non-natural from the programmer's view. If there is no 
> way to improve that at small cost, too bad...

But there is: don't define the static function inline; define it in
the implementation file only.  This will make sure the object file in
the library will be sucked in, bringing with it the static
initializers.

> Boy, I wanted to learn how to use libtool, it is an occasion...

Please note that libtool doesn't support any language other than C
yet, although it does work with g++, by luck, on a couple of
platforms.

-- 
Alexandre Oliva http://www.dcc.unicamp.br/~oliva IC-Unicamp, Bra[sz]il
oliva@{dcc.unicamp.br,guarana.{org,com}} aoliva@{acm.org,computer.org}
oliva@{gnu.org,kaffe.org,{egcs,sourceware}.cygnus.com,samba.org}
** I may forward mail about projects to mailing lists; please use them

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

* Re: C++ and static data members...
  1999-09-03 10:25 ` Joe Buck
  1999-09-03 12:29   ` Joern Rennecke
@ 1999-09-03 16:16   ` Theodore Papadopoulo
  1999-09-03 20:33     ` Alexandre Oliva
  1999-09-30 18:02     ` Theodore Papadopoulo
  1999-09-30 18:02   ` Joe Buck
  2 siblings, 2 replies; 22+ messages in thread
From: Theodore Papadopoulo @ 1999-09-03 16:16 UTC (permalink / raw)
  To: Joe Buck; +Cc: gcc, martin

First, let me be clear. I do not want a new feature. I just find the current 
behaviour strange and non-natural from the programmer's view. If there is no 
way to improve that at small cost, too bad...

> No, the purpose of a standard is to standardize existing practice, not
> to introduce new stuff that's never been seen before unless it fills
> a vital need.  You seem to want g++ to ignore all existing practice
> and include any .o file that has a static object with a constructor.

Well to most users (with a strong C predjudice, I must agree (but I'm n
ot a C++ beginner either)), if something works compiling a set of .o then
if you put part of your .o into a library and recompile with it instead,
it still works. That's existing practice also...

AFAICT, the static members initialization is the feature that makes
this behaviour to appear, so in some way it is a C++ ``concern'' (I'm 
trying to avoid the word problem).

As is by the way the concern of the order of such initializations across 
translation units. In fine, static members are not so easy to use !!! 
Too bad :-(

> This would be a disaster; executable sizes would bloat, and programs
> that depend on the existing behavior would break.

Size of executables might indeed be a problem. 
I'm not sure to see programs that would rely on such a strange 
behaviour (.o vs .a link properties)... but I have certainly not
seen everything :-)

> (example: use of static constructors to register information about what
> code has been included, or to implement the "object factory" pattern.  If
> this scheme is used, your proposed change would require that every file in
> every library be included in every executable).

The funny thing is that it is exactly what I wanted to do (register various 
file formats readers/writers).... Everything worked well untill I created the library...
I worked around my problem by putting the static variable definitions 
into the file that registers the information. That's a modularity 
disaster but it works fine. It is just more tricky to extend than it should 
have been...

> You always have the option of specifying the .o files you want explicitly
> on the linker command line.

IMHO, offer a library and then ask to people to link with a given .o plus 
the library is a no-no....

Actually, creating a dynamic library instead of a static one is maybe 
the easiest solution from both the implementer and the user point of 
view. Boy, I wanted to learn how to use libtool, it is an 
occasion...

	Thank's anyhow for all your clarifications...


--------------------------------------------------------------------
Theodore Papadopoulo
Email: Theodore.Papadopoulo@sophia.inria.fr Tel: (33) 04 92 38 76 01
 --------------------------------------------------------------------


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

* Re: C++ and static data members...
  1999-09-03 10:25 ` Joe Buck
@ 1999-09-03 12:29   ` Joern Rennecke
  1999-09-30 18:02     ` Joern Rennecke
  1999-09-03 16:16   ` Theodore Papadopoulo
  1999-09-30 18:02   ` Joe Buck
  2 siblings, 1 reply; 22+ messages in thread
From: Joern Rennecke @ 1999-09-03 12:29 UTC (permalink / raw)
  To: Joe Buck; +Cc: Theodore.Papadopoulo, gcc, martin, jbuck

> You always have the option of specifying the .o files you want explicitly
> on the linker command line.

Or easier to use in practive if you already have a library: just
tell the linker to start out with a global symbol from the wanted .o file
marked as undefined (i.e. the -u option of gnu ld).

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

* Re: C++ and static data members...
  1999-09-03 10:13 Theodore Papadopoulo
@ 1999-09-03 10:25 ` Joe Buck
  1999-09-03 12:29   ` Joern Rennecke
                     ` (2 more replies)
  1999-09-06 14:40 ` Martin v. Loewis
  1999-09-30 18:02 ` Theodore Papadopoulo
  2 siblings, 3 replies; 22+ messages in thread
From: Joe Buck @ 1999-09-03 10:25 UTC (permalink / raw)
  To: Theodore Papadopoulo; +Cc: gcc, martin, jbuck

[ static objects in a library may not be defined ]

> martin@mira.isdn.cs.tu-berlin.de said:
> > Please note that this is not in violation of the C++ standard, since
> > object file archives are not known to the standard. 
> 
> I was expecting such an answer... It seems also a little too simple 
> answer as I'm sure that the standard indeed makes implicitly 
> use of quite some knowledge of the object and linking technology, but 
> let's not discuss that.
> 
> However, your wording seems to mean that's a quality of 
> implementation issue (this is the right term to use when dealing with 
> letter vs spirit of the standard issues right?)

No, the purpose of a standard is to standardize existing practice, not
to introduce new stuff that's never been seen before unless it fills
a vital need.  You seem to want g++ to ignore all existing practice
and include any .o file that has a static object with a constructor.
This would be a disaster; executable sizes would bloat, and programs
that depend on the existing behavior would break.

(example: use of static constructors to register information about what
code has been included, or to implement the "object factory" pattern.  If
this scheme is used, your proposed change would require that every file in
every library be included in every executable).

There is no "spirit of the standard" that suggests that what you want
to occur, will occur.  The standard does not talk about files, libraries,
etc.  As far as the standard is concerned, some mechanism outside the
scope of the standard assembles all of the pieces of the program.  It
might be object files and libraries, or it might be a database.  The
passage you originally referred to then talks about what code can be
dropped or not dropped from this collection of pieces.  In this case,
the static objects in question are never part of the program in the
first place.

You always have the option of specifying the .o files you want explicitly
on the linker command line.

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

* Re: C++ and static data members...
@ 1999-09-03 10:13 Theodore Papadopoulo
  1999-09-03 10:25 ` Joe Buck
                   ` (2 more replies)
  0 siblings, 3 replies; 22+ messages in thread
From: Theodore Papadopoulo @ 1999-09-03 10:13 UTC (permalink / raw)
  To: gcc; +Cc: Martin v. Loewis, Joe Buck

martin@mira.isdn.cs.tu-berlin.de said:
> Well, you are missing an implementation restriction. You must not put
> the object files containing such globals in a library. Instead, you
> must pass them to the linking command line explicitly. 

jbuck@synopsys.com said:
> That last sentence is not very clear.  What actually happens is that
> the linker processes files and libraries on the command line left to
> right. It will not select an object file from a library unless that
> object file defines a global symbol that is currently undefined.  To
> oversimplify things a bit, initially only the symbol "main" is
> undefined (really it's a bit different: a startup function is chosen
> which calls main, but it gives you a picture of what's going on).

> If you want to be sure that a particular static object is included,
> you can make sure that the .o file that contains it also defines some
> global symbol that is referenced by some other file that must be
> included. 

Yes, I realized that. Anyway, thank's for the explanation and the tricks. 
It remains the fact that for C++ this can seem very weird.
I cannot think of the same kind of problem arising with C.

martin@mira.isdn.cs.tu-berlin.de said:
> Please note that this is not in violation of the C++ standard, since
> object file archives are not known to the standard. 

I was expecting such an answer... It seems also a little too simple 
answer as I'm sure that the standard indeed makes implicitly 
use of quite some knowledge of the object and linking technology, but 
let's not discuss that.

However, your wording seems to mean that's a quality of 
implementation issue (this is the right term to use when dealing with 
letter vs spirit of the standard issues right?) since it seems that
the behaviour of the compiling system (as opposed to the compiler itself)
is undefined in the current state. Am I right, or is the current behaviour
mandated somehow ?

If it is indeed a quality of implementation issue, then would it be
accepted to add something to correct this in g++ ?

In my naive view, it should not be extremely difficult to add references
to the static variables (only those that have a side effect if gcc can detect that)
in a special section (as for the exception handling info) named eg .always_link
at compile time and use collect2 to generate a .o file that names those variables and 
that would be inserted in the link line before the library.
Of course this is very ELF specific. There should be other ways 
to mark and detect the relevant variables (name mangling ??).
I do not know which method is the best but this seems feasible...

If this (or a variation of it) is acceptable, then I might try to do it 
(I might need of a little help however).

	Thank's for your audience,

	Theo.
 

 --------------------------------------------------------------------
 Theodore Papadopoulo
 Email: Theodore.Papadopoulo@sophia.inria.fr Tel: (33) 04 92 38 76 01
 --------------------------------------------------------------------



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

* Re: C++ and static data members...
  1999-09-02 15:52 Theodore Papadopoulo
  1999-09-02 16:27 ` Martin v. Loewis
@ 1999-09-02 16:41 ` Joe Buck
  1999-09-30 18:02   ` Joe Buck
  1999-09-30 18:02 ` Theodore Papadopoulo
  2 siblings, 1 reply; 22+ messages in thread
From: Joe Buck @ 1999-09-02 16:41 UTC (permalink / raw)
  To: Theodore Papadopoulo; +Cc: gcc

> The C++ standard explicitly states that:
> 3.7.1 2 If an object of static storage has initialization or 
> destructor with side effects, it shall not be eliminated even if it 
> appears to be unused, except that a class object or its copy may be 
> eliminated as specified in 12.8

Right, once the static object is included it may not be eliminated.
But we do not, by default, include all code that appears in a library.
(If the rule required that, then it would be impossible to implement
C++ using a standard Unix/Posix linker).  .o files are only sucked in
from libraries for the purpose of satisfying global symbol definitions.

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

* Re: C++ and static data members...
  1999-09-02 16:27 ` Martin v. Loewis
@ 1999-09-02 16:36   ` Joe Buck
  1999-09-30 18:02     ` Joe Buck
  1999-09-30 18:02   ` Martin v. Loewis
  1 sibling, 1 reply; 22+ messages in thread
From: Joe Buck @ 1999-09-02 16:36 UTC (permalink / raw)
  To: Martin v. Loewis; +Cc: Theodore.Papadopoulo, gcc

Martin Loewis writes:
> Well, you are missing an implementation restriction. You must not put
> the object files containing such globals in a library. Instead, you
> must pass them to the linking command line explicitly.
> 
> This is because of the way the linker works: it won't use object files
> from a library unless they are used.

That last sentence is not very clear.  What actually happens is that the
linker processes files and libraries on the command line left to right.
It will not select an object file from a library unless that object file
defines a global symbol that is currently undefined.  To oversimplify
things a bit, initially only the symbol "main" is undefined (really
it's a bit different: a startup function is chosen which calls main,
but it gives you a picture of what's going on).

If you want to be sure that a particular static object is included, you
can make sure that the .o file that contains it also defines some global
symbol that is referenced by some other file that must be included.



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

* Re: C++ and static data members...
  1999-09-02 15:52 Theodore Papadopoulo
@ 1999-09-02 16:27 ` Martin v. Loewis
  1999-09-02 16:36   ` Joe Buck
  1999-09-30 18:02   ` Martin v. Loewis
  1999-09-02 16:41 ` Joe Buck
  1999-09-30 18:02 ` Theodore Papadopoulo
  2 siblings, 2 replies; 22+ messages in thread
From: Martin v. Loewis @ 1999-09-02 16:27 UTC (permalink / raw)
  To: Theodore.Papadopoulo; +Cc: gcc

> I'm quite puzzled by the behaviour of the compiler (well actually the
> linker) for the small program given below. I'm certainly missing 
> something.... HUGE but I cannot figure out what.

Well, you are missing an implementation restriction. You must not put
the object files containing such globals in a library. Instead, you
must pass them to the linking command line explicitly.

This is because of the way the linker works: it won't use object files
from a library unless they are used.

If you absolutely want to use the library, and use are using GNU ld, you
can say

g++ -o a Main.C -L. -Wl,--whole-archive -lA -Wl,--no-whole-archive

That will use the entire library, including all static objects which
are not referenced otherwise.

Please note that this is not in violation of the C++ standard, since
object file archives are not known to the standard.

Regards,
Martin

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

* C++ and static data members...
@ 1999-09-02 15:52 Theodore Papadopoulo
  1999-09-02 16:27 ` Martin v. Loewis
                   ` (2 more replies)
  0 siblings, 3 replies; 22+ messages in thread
From: Theodore Papadopoulo @ 1999-09-02 15:52 UTC (permalink / raw)
  To: gcc

The C++ standard explicitly states that:
3.7.1 2 If an object of static storage has initialization or 
destructor with side effects, it shall not be eliminated even if it 
appears to be unused, except that a class object or its copy may be 
eliminated as specified in 12.8

I'm quite puzzled by the behaviour of the compiler (well actually the
linker) for the small program given below. I'm certainly missing 
something.... HUGE but I cannot figure out what. This is all the more 
annoying that I'm using this kind of construction in many libraries 
(I just wonder why I have not been struck by this before).

The example is done with:

mururoa->g++ -v
Reading specs from /usr/local/gcc/lib/gcc-lib/sparc-sun-solaris2.6/2.95.1/specs
gcc version 2.95.1 19990816 (release)

But the thing same happens with:

ouahu->g++ -v
Reading specs from /usr/local/gcc/lib/gcc-lib/i686-pc-linux-gnu/2.95.1/specs
gcc version 2.95.1 19990816 (release)

So its maybe an ELF specific problem but seems not a Solaris ld/gnu ld one...

mururoa->cat A.H
#include <stdio.h>
#include <iostream.h>

class A {
public:

        static void f() { cout << "I was here" << endl; }

private:

        A() { fprintf(stderr,"Constructing A\n"); }

        static const A proto;
};
// End of A.H

mururoa->cat A.C
#include "A.H"

const A A::proto;
// End of A.H

mururoa->g++ -c A.C 
mururoa->ar r libA.a A.o
ar: creating libA.a

mururoa->cat Main.C 
#include "A.H"

int
main()
{
        A::f();
}
// End of Main.C

mururoa->g++ Main.C -L. -lA
mururoa->./a.out 
I was here

The constructor for the static copy is never called!
And indeed nm shows that no code is linked for class A::A(void).

mururoa->g++ Main.C A.o
mururoa->./a.out
Constructing A
I was here

This one works as expected...

nm shows:
[484] |    256896|       1|OBJT |GLOB |0    |97     |A::proto
[128] |    108816|      32|FUNC |LOCL |0    |9      |global constructors keyed to A::proto
[725] |    169540|      52|FUNC |WEAK |0    |13     |A::A(void)

that were no present in the previous case.

 --------------------------------------------------------------------
 Theodore Papadopoulo
 Email: Theodore.Papadopoulo@sophia.inria.fr Tel: (33) 04 92 38 76 01
 --------------------------------------------------------------------



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

end of thread, other threads:[~1999-09-30 18:02 UTC | newest]

Thread overview: 22+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
1999-09-03 12:37 C++ and static data members David_Abrahams
1999-09-30 18:02 ` David_Abrahams
  -- strict thread matches above, loose matches on Subject: below --
1999-09-03 10:13 Theodore Papadopoulo
1999-09-03 10:25 ` Joe Buck
1999-09-03 12:29   ` Joern Rennecke
1999-09-30 18:02     ` Joern Rennecke
1999-09-03 16:16   ` Theodore Papadopoulo
1999-09-03 20:33     ` Alexandre Oliva
1999-09-30 18:02       ` Alexandre Oliva
1999-09-30 18:02     ` Theodore Papadopoulo
1999-09-30 18:02   ` Joe Buck
1999-09-06 14:40 ` Martin v. Loewis
1999-09-30 18:02   ` Martin v. Loewis
1999-09-30 18:02 ` Theodore Papadopoulo
1999-09-02 15:52 Theodore Papadopoulo
1999-09-02 16:27 ` Martin v. Loewis
1999-09-02 16:36   ` Joe Buck
1999-09-30 18:02     ` Joe Buck
1999-09-30 18:02   ` Martin v. Loewis
1999-09-02 16:41 ` Joe Buck
1999-09-30 18:02   ` Joe Buck
1999-09-30 18:02 ` Theodore Papadopoulo

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