Initialization of unused global variables from static libraries.

K

Keith H Duggar

Alf said:
Then §3.7.1/2 applies to those objects, but do you have a reference in
the standard for which objects /are/ "part of the program"?

"Phases of translation", [lex.phases], paragraph 1, bullet 9 describes
which library components become part of the program.

This is essentially a description of standard linker technology: link in
all the object files, then thumb through the libraries to resolve
unsatisfied external references.

Is "external usage" transitive? For example given

<code>
//in foolib/foo.cpp
bool fooInit ( ) { ... }
....
bool const TheInitDone = fooInit() ;
....
void foodo ( )
{
if ( TheInitDone ) {
...
} else {
abort() ;
}
}

//in main.cpp
int main ( )
{
foodo() ;
return 0 ;
}
</code>

"foodo" is "externally used" so its definition would be "part of
the program". Would this transitively make TheInitDone "externally
used" and therefore part of the program and thus fooInit as well?

Thanks again. This is huge. Can't believe I've been ignorant of
this subtlety all these years. Hmm I wonder if that core dump back
back in 2006 ... ;-)

KHD
 
A

Alf P. Steinbach

* Öö Tiib:
* Pete Becker:
Alf P. Steinbach wrote:
* Pete Becker:
Alf P. Steinbach wrote:
Especially considering that §3.7.1/2 only makes a difference for an
object that is not referenced, or "unused" as it says, -- that
that's what it's specifically about.
If it doesn't apply to the "unused" objects it says that it applies
to, then what?
"Unused" objects are objects that are part of the program but not
"used".
I can't find the qualification "are part of the program" in the standard.
Of course not. It's implicit in every part of the standard. The standard
doesn't need to say that the foo.obj on my hard drive is not part of
your program. It does need to say when and which objects and functions
in libraries are part of the program, and it does that.
I don't understand. The first sentence says that "Of course" I can't find it in
the standard, whereas the last sentence says that "it does [say which object and
functions ... are part of the program]", which apparenly is self-contradictory.
Where does the standard say this?

I think that closest thing is in 2.1/9 that mentions what will be
taken from library. But it feels that there you are back in round 1
interpreting these vague words. For me it means that library component
(probably translation unit in library?) is not linked into program
unless it satifies external references that are not yet resolved.

Yes, that's also how I read it.

E.g., if this is put in a library, and then linked, ...

#include <stdio.h>
int const x = printf( "blah blah\n" );
int main() {}

.... then I do not expect any difference from having it in an object file and
linking that object file, i.e. I do expect the output "blah blah" no matter the
physical packaging of the object code, be it in an object file, a library or
some other kind of repository, or even the Windows clipboard (TFSM forbid).

And assuming that the standard indeed requires the same result for the code
above regardless of the intermediate steps of the build, then if there is some
loophole where unreferenced static lifetime objects in libraries can be freely
eliminated, then one would need the special casing of the TU containing "main"
that Pete mentioned, "it is part of the program (here, because it's in the same
translation unit as main)", and that I can't find anywhere in the standard.


Cheers,

- Alf
 
M

Milan Radovich

I'd try an object with a constructor.

Unfortunately the results are similar. Seems like there is no choice but
turning to implementation-specific linker options.
 
M

Milan Radovich

"Unused" objects are objects that are part of the program but not "used".

static my_type m;

int main()
{
return 0;
}

Although 'm' is unused, it is part of the program (here, because it's in
the same translation unit as main) and it has to be constructed and
destroyed.

But if you put 'm' into a library, it's not part of the program unless
there is an external reference to it in the program. That's the point of
libraries: if you don't use it (in the colloquial sense) it doesn't have
to get linked in. If that weren't the case, "Hello, world" would have to
pull in the entire standard library.

If I understand correctly, then according to that interpretation if a static
library has more than one entity: for example, in addition to the original
foo/bar it defines function f(), then even if f() is used in the main program,
it still would be correct if "foo" is not printed, even though implementations
I have do print "foo" in this case.
 
A

Alf P. Steinbach

* Pete Becker:
That works because the implementation's startup code calls main, so
there's an external reference to main, which the linker resolves by
linking in that code.

Then it seems that we're up against the old
initialization-deferred-till-after-first-statement-of-main, where it only needs
to be done before the first call to or reference of (I can't recall exactly)
something in the TU.

Checking...

Yep, when I added a dummy function 'init' to the OP's B translation unit, and
called that dummy from A (main), then


<result>
C:\test> gnuc -c b.cpp

C:\test> gnuc -c a.cpp

C:\test> del *.a

C:\test> ar -r knurre.a b.o
ar: creating knurre.a

C:\test> gnuc a.o knurre.a

C:\test> a
foo

C:\test> _
</result>


So it wasn't that the static object wasn't referenced, it was that nothing in
the "main" TU referred to /anything at all/ in that TU. And the "main" TU is
referred to implicitly by "main" being referred to by the runtime. Although wrt.
to the formal that's not an argument that holds water, but it must be so.

Not sure if that's what you've been trying to say all the time?


Cheers,

- Alf
 
Ö

Öö Tiib

* Öö Tiib:




* Pete Becker:
Alf P. Steinbach wrote:
* Pete Becker:
Alf P. Steinbach wrote:
Especially considering that §3.7.1/2 only makes a difference for an
object that is not referenced, or "unused" as it says,  --  that
that's what it's specifically about.
If it doesn't apply to the "unused" objects it says that it applies
to, then what?
"Unused" objects are objects that are part of the program but not
"used".
I can't find the qualification "are part of the program" in the standard.
Of course not. It's implicit in every part of the standard. The standard
doesn't need to say that the foo.obj on my hard drive is not part of
your program. It does need to say when and which objects and functions
in libraries are part of the program, and it does that.
I don't understand. The first sentence says that "Of course" I can't find it in
the standard, whereas the last sentence says that "it does [say which object and
functions ... are part of the program]", which apparenly is self-contradictory.
Where does the standard say this?
I think that closest thing is in 2.1/9 that mentions what will be
taken from library. But it feels that there you are back in round 1
interpreting these vague words. For me it means that library component
(probably translation unit in library?) is not linked into program
unless it satifies external references that are not yet resolved.

Yes, that's also how I read it.

E.g., if this is put in a library, and then linked, ...

   #include <stdio.h>
   int const x = printf( "blah blah\n" );
   int main() {}

... then I do not expect any difference from having it in an object file and
linking that object file, i.e. I do expect the output "blah blah" no matter the
physical packaging of the object code, be it in an object file, a library or
some other kind of repository, or even the Windows clipboard (TFSM forbid).

And assuming that the standard indeed requires the same result for the code
above regardless of the intermediate steps of the build, then if there is some
loophole where unreferenced static lifetime objects in libraries can be freely
eliminated, then one would need the special casing of the TU containing "main"
that Pete mentioned, "it is part of the program (here, because it's in the same
translation unit as main)", and that I can't find anywhere in the standard.

Yes, 3.6.1. as "int main(int argc, char* argv[])" or "int main()" must
be defined somewhere. That together with discriminating to poor
translation units that are in library 2.1/9 is perhaps the ground of
selection.

So:
main is one of external references that must be resolved.
Anything in same translation unit with main must be resolved as well.
References from vagabond translation units that are not tied into
libraries but are linked must be resolved.
When some translation unit from library is taken to resolve things
then again, what it leaves unresolved should be resolved.
 
K

Keith H Duggar

Well, yes, sort of. <g> Unix linkers typically made a single pass
through the list of library files, and if there were still unresolved
symbols they reported an error and quit. So you sometimes had to list
the same library file several times on the command line. These days they
pretty much know to go through everything, repeating until all external
references have been resolved, or until no new files have been linked
in; in the latter case, the unresolved symbols are reported as not found.

I haven't tested it with 4.0 gnu but with 3.3 it was still the
case that it was single pass through the /list/ of files but it
would resolve transitively all symbols within each lib file. So
one still had to list libraries more than once but only to
resolve transitivity /between/ different libraries.

Was their a time when Unix linkers would not even transitively
resolve /within/ a single library?

Sorry for being thick, but you can please confirm that for my
exmaple

<code>
//in foolib/foo.cpp
bool fooInit ( ) { return true ; }
....
bool const TheInitDone = fooInit() ;
....
void foodo ( )
{
if ( TheInitDone ) {
...
} else {
abort() ;
}
}

//in main.cpp
int main ( )
{
foodo() ;
return 0 ;
}
</code>

a conforming C++ platform must either 1) dynamically initialize
TheInitDone by calling fooInit() or 2) fail to produce a program.
Or put another way, given the code above, the main's foodo() call
cannot trigger the foodo() abort for a conforming platform?

KHD
 
A

Alf P. Steinbach

* Alf P. Steinbach:
* Milan Radovich:

No, regardless of how the code is physically packaged.

§3.7.1/2 "If an object of static storage duration has initialization or
a 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".

§12.8 then talks about elimination of copy constructor calls, in
§12.8/15, which is not your case.

As it turned out by discussion with Pete Becker, I was wrong about this.

Hm, I can't even blame lack of coffee, even though I was a bit tired. Well,
that's enough. Good excuse! :) Bad extra defense: now that some wool has been
removed I recall writing about this problem earlier, at length. Oh well.

The crucial insight is that only translation units that are somehow referenced
by code, need to be included in the final program, and that §3.7.1 and the rest
of the standard only applies to code in the actually included TU's.

Translation unit [a.cc] is referenced & therefore included by virtue of
containing "main", but there's no reference to anything in [b.cc].

So, a simple fix is to reference something in [b.cc], e.g. a call of some dummy
function there.

Pitfall for the simple fix: the standard's §3.6.2/3 supports deferring the
dynamic initialization of statics in a TU until the first call of a function or
reference of an object in the TU. This can play havoc with using e.g. a factory
where types have installed themselves via the dynamic initialization of statics
in their translation units, if the use of the factory occurs before the first
call of a function or reference of object in some self-registering type's TU.

I'd try an object with a constructor.

I'd now instead try to reference something in the TU.


Cheers & hth.,

- Alf
 
F

Fred Zwarts

Pete Becker said:
If that was the intention, the wording would have been about
"translated translation units" and "instantiation units" instead of
"library components". It's deliberately a bit fuzzy in order to allow
various mechanisms. So the rule for objects is that if it's in a
library, you'd better have an external reference to it somewhere in
your program. If you want it, ask for it.

If it is intentional, I regret it.
The creator of a library component has a reason to put things
together in a translation unit. The maker of the "main program"
often does not know such details of a library component,
so why should he be asked to specify such details in the main program?
It makes the maintenance of such programs difficult in case
the implementation of a library changes.
If the maker of the library knows that objects can be eliminated,
without loss of functionality of other objects or function
he can put them in different translation units,
but how can he express that an object is required for other
functions or objects within the same translation unit other than
putting them together in a translation unit?
 
Ö

Öö Tiib

If it is intentional, I regret it.
The creator of a library component has a reason to put things
together in a translation unit. The maker of the "main program"
often does not know such details of a library component,
so why should he be asked to specify such details in the main program?
It makes the maintenance of such programs difficult in case
the implementation of a library changes.
If the maker of the library knows that objects can be eliminated,
without loss of functionality of other objects or function
he can put them in different translation units,
but how can he express that an object is required for other
functions or objects within the same translation unit other than
putting them together in a translation unit?

Translation units that are in libraries are linked into program only
if they resolve some unresolved external references.
The translation units that are not put into libraries but explicitly
linked into program are no subject of such selection and are always
linked into program. (Sounds terribly tautological but appears that it
is part that feels as ungranted to most people.)

What to do: Make a translation unit that externally references
something from every translation unit in libraries that you want to
link into program no matter what. Link such translation unit
explicitly and not as part of library.
 
M

Milan Radovich

Translation unit [a.cc] is referenced & therefore included by virtue of
containing "main", but there's no reference to anything in [b.cc].

So, a simple fix is to reference something in [b.cc], e.g. a call of some dummy
function there.

According to Pete's interpretation (see his reply to my post in the same
discussion subthread you are referring to) this is not enough: you may
need to reference a variable who's initialization should have a side effect.
Referencing some dummy function won't be enough unless that function
uses the said variable.

In my case: if you add dummy function "void f(){}" to b.cc and call
it from a.cc, initialization of bar is implementation detail and won't
necessarily occur. In order to ensure bar's initialization, bar itself
should be referenced from a.cc (or f should use bar).
 
A

Alf P. Steinbach

* Milan Radovich:
Translation unit [a.cc] is referenced & therefore included by virtue of
containing "main", but there's no reference to anything in [b.cc].

So, a simple fix is to reference something in [b.cc], e.g. a call of some dummy
function there.

According to Pete's interpretation (see his reply to my post in the same
discussion subthread you are referring to) this is not enough: you may
need to reference a variable who's initialization should have a side effect.
Referencing some dummy function won't be enough unless that function
uses the said variable.

In my case: if you add dummy function "void f(){}" to b.cc and call
it from a.cc, initialization of bar is implementation detail and won't
necessarily occur. In order to ensure bar's initialization, bar itself
should be referenced from a.cc (or f should use bar).

This seems overly, extremely pessimistic. I'm sure that it would be mentioned in
the standard if it was intended to be this way. But despite some extensive
debate in this thread, no such mention in the standard has been found.

Instead the standard goes to great lengths to explicitly point out what can't be
eliminated.

In particular §3.7.1/2 "If an object of static storage duration has
initialization or a 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", as I've mentioned & quoted a few times.


Cheers & hth.,

- Alf
 
F

Fred Zwarts

Öö Tiib said:
Translation units that are in libraries are linked into program only
if they resolve some unresolved external references.
The translation units that are not put into libraries but explicitly
linked into program are no subject of such selection and are always
linked into program. (Sounds terribly tautological but appears that it
is part that feels as ungranted to most people.)

What to do: Make a translation unit that externally references
something from every translation unit in libraries that you want to
link into program no matter what. Link such translation unit
explicitly and not as part of library.

But if understand correctly, this it not enough.
It should not only reference something, but it should reference everything
from a translation unit in a library. Otherwise, only that "something" is linked in
and the other parts of the translation unit are eliminated.
This is a problem for maintenance and modularity.
 
Ö

Öö Tiib

But if understand correctly, this it not enough.
It should not only reference something, but it should reference everything
from a translation unit in a library. Otherwise, only that "something" is linked in
and the other parts of the translation unit are eliminated.
This is a problem for maintenance and modularity.

How so? Standard does not use word "something". Standard say (2.1/9)
"library component". Standard say that translation units can be put
into libraries (2/2) so i assume that translation unit is library
component when it has been put into library. Standard nowhere
describes how it splits translation units into subcomponents.
Implementation might only optimize out and eliminate something. Such
places that describe what is forbidden to eliminate have been cited
several times by Alf and Pete in this thread.
 
F

Fred Zwarts

Öö Tiib said:
How so? Standard does not use word "something". Standard say (2.1/9)
"library component". Standard say that translation units can be put
into libraries (2/2) so i assume that translation unit is library
component when it has been put into library. Standard nowhere
describes how it splits translation units into subcomponents.
Implementation might only optimize out and eliminate something. Such
places that describe what is forbidden to eliminate have been cited
several times by Alf and Pete in this thread.

This was my understanding, too, But Pete wrote (see above):
 
P

Paul Bibbings

Alf P. Steinbach said:
* Milan Radovich:
Translation unit [a.cc] is referenced & therefore included by
virtue of containing "main", but there's no reference to anything
in [b.cc].

So, a simple fix is to reference something in [b.cc], e.g. a call
of some dummy function there.

According to Pete's interpretation (see his reply to my post in the same
discussion subthread you are referring to) this is not enough: you
may need to reference a variable who's initialization should have a
side effect. Referencing some dummy function won't be enough unless
that function uses the said variable.

In my case: if you add dummy function "void f(){}" to b.cc and call
it from a.cc, initialization of bar is implementation detail and won't
necessarily occur. In order to ensure bar's initialization, bar itself
should be referenced from a.cc (or f should use bar).

This seems overly, extremely pessimistic. I'm sure that it would be
mentioned in the standard if it was intended to be this way. But
despite some extensive debate in this thread, no such mention in the
standard has been found.

Instead the standard goes to great lengths to explicitly point out
what can't be eliminated.

In particular §3.7.1/2 "If an object of static storage duration has
initialization or a 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", as I've mentioned
& quoted a few times.

But Alf, I understood from the discussion so far that there is indeed
only a requirement that code that is required is linked in, to satisfy
external references; that, whilst it /is/ the case that g++ will link in
a whole translation unit (object file) from a library, that this is
indeed implementation dependent - that there is no requirement that it
do so. Hence, for portability reason, I would say that Milan's concern
is a valid one.

As Pete referenced in an earlier post:

[lex.phases] 2.2/1-9
"All external entity references are resolved. Library components are
linked to satisfy external references to entities not defined in the
current translation. ..."

It is only the fact that g++ is not applying a "smart linking" model -
bringing in *only* what is required to satisfy external references -
that the kind of initialization that Milan is looking for is not
guaranteed. As has been seen, g++ can guarantee this as an
implementation detail, but the Standard doesn't require it, as long as
external references are satisfied.

Regards

Paul Bibbings
 
A

Alf P. Steinbach

* Paul Bibbings:
Alf P. Steinbach said:
* Milan Radovich:
Translation unit [a.cc] is referenced & therefore included by
virtue of containing "main", but there's no reference to anything
in [b.cc].

So, a simple fix is to reference something in [b.cc], e.g. a call
of some dummy function there.
According to Pete's interpretation (see his reply to my post in the same
discussion subthread you are referring to) this is not enough: you
may need to reference a variable who's initialization should have a
side effect. Referencing some dummy function won't be enough unless
that function uses the said variable.

In my case: if you add dummy function "void f(){}" to b.cc and call
it from a.cc, initialization of bar is implementation detail and won't
necessarily occur. In order to ensure bar's initialization, bar itself
should be referenced from a.cc (or f should use bar).
This seems overly, extremely pessimistic. I'm sure that it would be
mentioned in the standard if it was intended to be this way. But
despite some extensive debate in this thread, no such mention in the
standard has been found.

Instead the standard goes to great lengths to explicitly point out
what can't be eliminated.

In particular §3.7.1/2 "If an object of static storage duration has
initialization or a 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", as I've mentioned
& quoted a few times.

But Alf, I understood from the discussion so far that there is indeed
only a requirement that code that is required is linked in, to satisfy
external references; that, whilst it /is/ the case that g++ will link in
a whole translation unit (object file) from a library, that this is
indeed implementation dependent - that there is no requirement that it
do so. Hence, for portability reason, I would say that Milan's concern
is a valid one.

As Pete referenced in an earlier post:

[lex.phases] 2.2/1-9
"All external entity references are resolved. Library components are
linked to satisfy external references to entities not defined in the
current translation. ..."

It is only the fact that g++ is not applying a "smart linking" model -
bringing in *only* what is required to satisfy external references -
that the kind of initialization that Milan is looking for is not
guaranteed. As has been seen, g++ can guarantee this as an
implementation detail, but the Standard doesn't require it, as long as
external references are satisfied.

Hm, let's be careful so as not to misrepresent Pete.

Here's the last thing he wrote in this thread:

an external reference, and putting init in the same translation unit as the
static object typically means that linking in init will also pull in the
static object. But that's not required; the only requirement is that init
get linked in.

Whoops, I take back that last sentence. Yes, calling a function requires
that static objects in the same translation unit get linked in.

Which means a little change of heart (just as I had to revise my view, but in my
case rather more than that).

However that doesn't mean that his earlier comment about "library component" was
wrongo.

Hypothetically one can envision a "library" where you have, as a "library
component" to be linked, an individual function from a translation unit, say (of
course you've made sure that it has no dependencies on static objects). I'm not
sure how well that plays with other rules of the standard. But the main thing is
that as long you don't use such an esoteric scheme, you're dealing with TU's,
and given that you're dealing with TU's, which you are, §3.7.1/2 applies --
except for very old versions of MSVC, if I recall correctly... ;-)


Cheers & hth.,

- Alf
 
Ö

Öö Tiib

This was my understanding, too, But Pete wrote (see above):

Ok, possibly Pete is right. Then you have to make a translation
unit(s) that you do not put into library but link explicitly and that
references externally things that you want (or recursively, things
that reference things you want).
 
K

Keith H Duggar

* Paul Bibbings:
* Milan Radovich:
Translation unit [a.cc] is referenced & therefore included by
virtue of containing "main", but there's no reference to anything
in [b.cc].
So, a simple fix is to reference something in [b.cc], e.g. a call
of some dummy function there.
According to Pete's interpretation (see his reply to my post in the same
discussion subthread you are referring to) this is not enough: you
may need to reference a variable who's initialization should have a
side effect. Referencing some dummy function won't be enough unless
that function uses the said variable.
In my case: if you add dummy function "void f(){}" to b.cc and call
it from a.cc, initialization of bar is implementation detail and won't
necessarily occur. In order to ensure bar's initialization, bar itself
should be referenced from a.cc (or f should use bar).
This seems overly, extremely pessimistic. I'm sure that it would be
mentioned in the standard if it was intended to be this way. But
despite some extensive debate in this thread, no such mention in the
standard has been found.
Instead the standard goes to great lengths to explicitly point out
what can't be eliminated.
In particular §3.7.1/2 "If an object of static storage duration has
initialization or a 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", as I've mentioned
& quoted a few times.
But Alf, I understood from the discussion so far that there is indeed
only a requirement that code that is required is linked in, to satisfy
external references; that, whilst it /is/ the case that g++ will link in
a whole translation unit (object file) from a library, that this is
indeed implementation dependent - that there is no requirement that it
do so. Hence, for portability reason, I would say that Milan's concern
is a valid one.
As Pete referenced in an earlier post:
[lex.phases] 2.2/1-9
"All external entity references are resolved. Library components are
linked to satisfy external references to entities not defined in the
current translation. ..."
It is only the fact that g++ is not applying a "smart linking" model -
bringing in *only* what is required to satisfy external references -
that the kind of initialization that Milan is looking for is not
guaranteed. As has been seen, g++ can guarantee this as an
implementation detail, but the Standard doesn't require it, as long as
external references are satisfied.

Hm, let's be careful so as not to misrepresent Pete.

Here's the last thing he wrote in this thread:
Pete Becker wrote:
an external reference, and putting init in the same translation unit as the
static object typically means that linking in init will also pull in the
static object. But that's not required; the only requirement is that init
get linked in.
Whoops, I take back that last sentence. Yes, calling a function requires
that static objects in the same translation unit get linked in.

Which means a little change of heart (just as I had to revise my view, but in my
case rather more than that).

However that doesn't mean that his earlier comment about "library component" was
wrongo.

Hypothetically one can envision a "library" where you have, as a "library
component" to be linked, an individual function from a translation unit, say (of
course you've made sure that it has no dependencies on static objects). I'm not
sure how well that plays with other rules of the standard. But the main thing is
that as long you don't use such an esoteric scheme, you're dealing with TU's,
and given that you're dealing with TU's, which you are, §3.7.1/2 applies --
except for very old versions of MSVC, if I recall correctly... ;-)

Eh, I'm not sure I would call such schemes "esoteric". Function
level linking and other smart linking techniques are valuable
optimization tools. I've /wished/ that gnu supported this out
of the box.

Utility aside, what in the standard /guarantees/ that all static
objects in a TU are "part of the program" if /any/ symbol in that
TU is referenced?

I certainly believe that the transitive closure of symbols is
part of the program, but all them? Just because they happen to
be in the same TU? Where is this guarantee?

Thanks!

KHD
 
P

Paul Bibbings

Alf P. Steinbach said:
* Paul Bibbings:
But Alf, I understood from the discussion so far that there is indeed
only a requirement that code that is required is linked in, to satisfy
external references; that, whilst it /is/ the case that g++ will link in
a whole translation unit (object file) from a library, that this is
indeed implementation dependent - that there is no requirement that it
do so. Hence, for portability reason, I would say that Milan's concern
is a valid one.

As Pete referenced in an earlier post:

[lex.phases] 2.2/1-9
"All external entity references are resolved. Library components are
linked to satisfy external references to entities not defined in the
current translation. ..."

It is only the fact that g++ is not applying a "smart linking" model -
bringing in *only* what is required to satisfy external references -
that the kind of initialization that Milan is looking for is not
guaranteed. As has been seen, g++ can guarantee this as an
implementation detail, but the Standard doesn't require it, as long as
external references are satisfied.

Hm, let's be careful so as not to misrepresent Pete.

Of course.
Here's the last thing he wrote in this thread:

Okay. That's clear. I must have missed that. Then there does appear
to be a guarantee here. Do we have a reference to this yet? And, by
`this', I mean specifically that all static objects in a library
translation unit are linked in, even where they are not referenced
directly; that is, that the behaviour we have seen so far for the
examples as g++ compiles them is guaranteed. (Not that I'm doubting the
claim, in any sense, of course.)

Regards

Paul Bibbings
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top