Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > Initialization of unused global variables from static libraries.

Reply
Thread Tools

Initialization of unused global variables from static libraries.

 
 
Fred Zwarts
Guest
Posts: n/a
 
      04-19-2010
"Milan Radovich" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed)
> On Mon, 19 Apr 2010 00:27:47 +0200, "Balog Pal" <(E-Mail Removed)> wrote:
>
>>> 2) Is there is a pattern which forces linker to add such a code to
>>> an executable?

>>
>> Sure, call function in that routine. Or use an implement-specific
>> way to force an extern/import symbol in one of your objects.

>
> The code should be multiplatform and therefore very general, therefore
> implementation-specific solutions are not suitable. Neither is
> function call, as I just explained in reply to other posts in the
> thread.


Libraries and linkers are platform specific, anyhow.
Maybe you can put the import of a symbol in the linker description,
so that you don't need to make your C++ code platform specific,
but only the build procedure, which is already platform specific.
 
Reply With Quote
 
 
 
 
Alf P. Steinbach
Guest
Posts: n/a
 
      04-19-2010
* Milan Radovich:
> Hello,
>
> I have 2 files:
>
> a.cc:
> ---------------------------------------
> int main()
> {
> return 0;
> }
> ---------------------------------------
>
> b.cc:
> ---------------------------------------
> #include <iostream>
>
> bool foo()
> {
> std::cout << "foo" << std::endl;
> return true;
> }
>
> const bool bar = foo();
> ---------------------------------------
>
> If I compile the application like that:
>
> g++ -c a.cc b.cc
> g++ a.o b.o -o a
>
> then when application is executed, it outputs a string "foo".
>
> But if I create a static library from b.cc and then link application
> with that library, like that:
>
> g++ -c a.cc b.cc
> ar rcs libb.a b.o
> g++ -L. -lb a.o -o a2
>
> then when application is ran, it doesn't print anything.
>
> After I searched for the reason why this happens, I found that
> when linking with static libraries, linker omits code which is not
> reachable through any execution path.
>
> The question is:
>
> 1) Is it a correct behaviour according to a Standard?


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.


> 2) Is there is a pattern which forces linker to add such a code to an
> executable?


I'd try an object with a constructor.


Cheers & hth.,

- Alf
 
Reply With Quote
 
 
 
 
Alf P. Steinbach
Guest
Posts: n/a
 
      04-19-2010
* Pete Becker:
> Alf P. Steinbach wrote:
>> * Milan Radovich:
>>> Hello,
>>>
>>> I have 2 files:
>>>
>>> a.cc:
>>> ---------------------------------------
>>> int main()
>>> {
>>> return 0;
>>> }
>>> ---------------------------------------
>>>
>>> b.cc:
>>> ---------------------------------------
>>> #include <iostream>
>>>
>>> bool foo()
>>> {
>>> std::cout << "foo" << std::endl;
>>> return true;
>>> }
>>>
>>> const bool bar = foo();
>>> ---------------------------------------
>>>
>>> If I compile the application like that:
>>>
>>> g++ -c a.cc b.cc
>>> g++ a.o b.o -o a
>>>
>>> then when application is executed, it outputs a string "foo".
>>>
>>> But if I create a static library from b.cc and then link application
>>> with that library, like that:
>>>
>>> g++ -c a.cc b.cc
>>> ar rcs libb.a b.o
>>> g++ -L. -lb a.o -o a2
>>>
>>> then when application is ran, it doesn't print anything.
>>>
>>> After I searched for the reason why this happens, I found that
>>> when linking with static libraries, linker omits code which is not
>>> reachable through any execution path.
>>>
>>> The question is:
>>>
>>> 1) Is it a correct behaviour according to a Standard?

>>
>> No, regardless of how the code is physically packaged.
>>

>
> It's a subtle point, but the object does not have to be constructed
> because it's not part of the program. See "Phases of translation",
> [lex.phases], paragraph 1, bullet 9. The second sentence is what matters
> here: "Library components are linked to satisfy external references to
> entities not defined in the current translation." If there are no
> external references to the object, it doesn't have to be linked in (and
> arguably should not be linked in).


Generally I wouldn't dream of contradicting you on the basic meaning of the
standard.

However §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" seems to much more clearly & directly /require/ the initialization.

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?

My only guess for a way that your interpretation could be right would be the
weasel words "appears to" that are used in §3.7.1/2, but what could that refer
to other than appearances wrt. linking?


Cheers,

- Alf
 
Reply With Quote
 
Keith H Duggar
Guest
Posts: n/a
 
      04-19-2010
On Apr 19, 9:42 am, Pete Becker <(E-Mail Removed)> wrote:
> Alf P. Steinbach wrote:
> > * Milan Radovich:
> >> Hello,

>
> >> I have 2 files:

>
> >> a.cc:
> >> ---------------------------------------
> >> int main()
> >> {
> >> return 0;
> >> }
> >> ---------------------------------------

>
> >> b.cc:
> >> ---------------------------------------
> >> #include <iostream>

>
> >> bool foo()
> >> {
> >> std::cout << "foo" << std::endl;
> >> return true;
> >> }

>
> >> const bool bar = foo();
> >> ---------------------------------------

>
> >> If I compile the application like that:

>
> >> g++ -c a.cc b.cc
> >> g++ a.o b.o -o a

>
> >> then when application is executed, it outputs a string "foo".

>
> >> But if I create a static library from b.cc and then link application
> >> with that library, like that:

>
> >> g++ -c a.cc b.cc
> >> ar rcs libb.a b.o
> >> g++ -L. -lb a.o -o a2

>
> >> then when application is ran, it doesn't print anything.

>
> >> After I searched for the reason why this happens, I found that
> >> when linking with static libraries, linker omits code which is not
> >> reachable through any execution path.

>
> >> The question is:

>
> >> 1) Is it a correct behaviour according to a Standard?

>
> > No, regardless of how the code is physically packaged.

>
> It's a subtle point, but the object does not have to be constructed
> because it's not part of the program. See "Phases of translation",
> [lex.phases], paragraph 1, bullet 9. The second sentence is what matters
> here: "Library components are linked to satisfy external references to
> entities not defined in the current translation." If there are no
> external references to the object, it doesn't have to be linked in (and
> arguably should not be linked in).


Yikes! This is new to me. So from time to time I use an idiom
like this:

in file foolib/foo.cpp
<code>
namespace {

class FooGuard {
public :
FooGuard ( ) {
//library initialization activity
}
~FooGuard ( ) {
//library teardown activity
}
} ;

FooGuard TheFooGuard ;
}
</code>

Obviously TheFooGuard has external linkage but there will be no
"external references" to the object if I understand that term. And
if I understand you point correctly then this idiom is broken??

Thanks for the help!

KHD
 
Reply With Quote
 
Fred Zwarts
Guest
Posts: n/a
 
      04-19-2010
"Pete Becker" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed)
> Alf P. Steinbach wrote:
>> * Milan Radovich:
>>> Hello,
>>>
>>> I have 2 files:
>>>
>>> a.cc:
>>> ---------------------------------------
>>> int main()
>>> {
>>> return 0;
>>> }
>>> ---------------------------------------
>>>
>>> b.cc:
>>> ---------------------------------------
>>> #include <iostream>
>>>
>>> bool foo()
>>> {
>>> std::cout << "foo" << std::endl;
>>> return true;
>>> }
>>>
>>> const bool bar = foo();
>>> ---------------------------------------
>>>
>>> If I compile the application like that:
>>>
>>> g++ -c a.cc b.cc
>>> g++ a.o b.o -o a
>>>
>>> then when application is executed, it outputs a string "foo".
>>>
>>> But if I create a static library from b.cc and then link application
>>> with that library, like that:
>>>
>>> g++ -c a.cc b.cc
>>> ar rcs libb.a b.o
>>> g++ -L. -lb a.o -o a2
>>>
>>> then when application is ran, it doesn't print anything.
>>>
>>> After I searched for the reason why this happens, I found that
>>> when linking with static libraries, linker omits code which is not
>>> reachable through any execution path.
>>>
>>> The question is:
>>>
>>> 1) Is it a correct behaviour according to a Standard?

>>
>> No, regardless of how the code is physically packaged.
>>

>
> It's a subtle point, but the object does not have to be constructed
> because it's not part of the program. See "Phases of translation",
> [lex.phases], paragraph 1, bullet 9. The second sentence is what
> matters here: "Library components are linked to satisfy external
> references to entities not defined in the current translation." If
> there are no external references to the object, it doesn't have to be
> linked in (and arguably should not be linked in).


Interesting. What is the definition of a library component?
Assuming that a library component is a translation unit:
If a library component is linked in, should it be linked in completely,
or is it also allowed to link in only those parts from a library component
that satisfy external references?
(Sorry for asking, but I don't have my copy of the standard here.)
 
Reply With Quote
 
Fred Zwarts
Guest
Posts: n/a
 
      04-19-2010
"Pete Becker" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed)
> 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".


Does the standard make a difference between "unused" and "not referenced"?

It is very well possible that a variable is not referenced, but it is used in the main program.
I often use a technique in which a translation unit other than the main program,
defines a static variable with a factory. The constructor adds the factory to a global list of factories.
The main program only references the same global list. In this way the program can use the factory
without referencing it. (This makes it possible to add factories without any change to the main program.)
In this case the factory static variable is used, but not referenced by the main program.
The addition of such variables, although they are not referenced, by the main program,
makes that the main program has a very different functionality.

I thought that this was exactly the reason why it says:
§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 ..."

The destructor of the factory class has a side effect (adding itself to a list),
so it should not be eliminated. I don't understand why this should not hold for
library entities. (The term object is ambiguous when talking about C++ and about compilers.)

 
Reply With Quote
 
Fred Zwarts
Guest
Posts: n/a
 
      04-19-2010
"Pete Becker" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed)
> Fred Zwarts wrote:
>>
>> Interesting. What is the definition of a library component?

>
> It's not defined. The old Unix rule was that each source file gets
> compiled into an object file, and each object file is a single entity:
> either it gets linked in in its entirety, or it doesn't get linked in.
> Some compilers produce object files with finer granularity: the linker
> can pull in only the parts that are actually needed, and ignore other
> parts of the object file.
>
>> Assuming that a library component is a translation unit:
>> If a library component is linked in, should it be linked in
>> completely, or is it also allowed to link in only those parts from a
>> library component that satisfy external references?

>
> Yes. <g>


If the term "library component" is not defined,
then the question could equally well be answered with No.

But, as C++ talks in terms of translation units, I think that the linker
should not eliminate parts of a unit, execpt if it can deduce that it has no effect
on the execution of a program. Even variables that are not referenced can
have effects on the execution of a program, as I said in another post.
Maybe the new standard should define this more clearly.
 
Reply With Quote
 
Alf P. Steinbach
Guest
Posts: n/a
 
      04-19-2010
* 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.

In particular, the definition of "used" in §3.2/2 (the ODR) does not have that
qualification.

Chapter & verse, please?


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


Sorry, again, chapter & verse for the "part of the program" qualification would
be nice.

Also, chapter & verse for the special casing of the TU containing "main" would
be very nice, since the idea is so strongly tied to & fundamental in your POV.

I'm unable to find it anywhere.


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


On the contrary, §2/1 notes that "A C++ program need [sic] not all be translated
at the same time".

The standard then goes on to explain in §2/2 that translation units (which
literally are parts of the program) can be put in e.g. libraries.

I.e., being in a library is not incompatible with being a "part of the program",
at least in the literal meaning -- but does the standard define the term?


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


Nope.

The linker only needs to pull in those things referenced directly or indirectly
by "main" or by static objects that under §3.7.1/2 can't be eliminated.


Cheers,

- Alf
 
Reply With Quote
 
Alf P. Steinbach
Guest
Posts: n/a
 
      04-19-2010
* 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?


> Once an object
> is part of the program, the rest of the standard applies to it.


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"?

For the response you're responding to I dug up an old posting by Steve Clamage
who also referred to this wooly concept-without-reference, essentially sharing
your POV. Then in a later thread Dave Abrahams implicitly adopted my POV here.
There was also one thread with Francis Glassborow, but unclear about his view.

But no matter the authority arguments (and you're definitely an authority, which
is why I'm taking your claim seriously); I think §3.7.1/2 is extremely clear,
that unused objects can't be eliminated when they have initialization or
destruction with side effect, and would be /meaningless/ under your POV where it
depends on the physical packaging of translation units, and where it depends on
whether an object is defined in the "main" function's TU.

Do you have a reference for the special-casing of the "main" function's TU?

I think if the standard's discussion of that special casing of the "main" TU was
found, then one could perhaps start to nest to find more info.


Cheers,

- Alf
 
Reply With Quote
 
Öö Tiib
Guest
Posts: n/a
 
      04-19-2010
On Apr 19, 8:19*pm, "Alf P. Steinbach" <(E-Mail Removed)> wrote:
> * 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.
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
global variables initialization paresh C Programming 20 11-24-2008 09:18 PM
does value-initialization happen for global and local static object ? subramanian100in@yahoo.com, India C++ 1 04-21-2008 03:17 AM
global variable vs static member initialization order n.torrey.pines@gmail.com C++ 10 03-15-2007 02:21 PM
Global (static) Var in a library initialization question. Kyle C++ 6 11-10-2005 03:43 PM
Initialization of global variables Rahul Gandhi C Programming 3 02-02-2004 05:30 PM



Advertisments