Re: Forced inclusion of "unused" objects
On Dec 10, 11:15 pm, Joshua Maurice <joshuamaur...@gmail.com> wrote:
On Dec 10, 2:32 am, James Kanze <james.ka...@gmail.com> wrote:
On Dec 9, 11:00 pm, Joshua Maurice <joshuamaur...@gmail.com> wrote:
On Dec 9, 4:17 am, James Kanze <james.ka...@gmail.com> wrote:
[...]
As I said else-thread, I just have a knee-jerk reaction to allowances
in the standard which allow the implementation to silently change the
behavior of the program in a platform dependent manner, such as
optimizing away unused translation units at whim, optimizing away
infinite loops, and so on.
I agree with you there (and you should add silently suppressing
a copy), but that's not what's happening in this case. The
issue here is that you're not including the translation unit in
the final program.
I'm bias-ed. I recognize that silently suppressing a copy does change
program semantics, but it's been there since the beginning for me,
The way libraries work is even older:-).
and
it's a much more sensible allowance than the other named allowances.
(I'll avoid the full rant which I recently made in both comp.std.c++
and comp.lang.c++.moderated. The rant did specifically mention copy
constructor elision as a direct parallel, although one I support.)
But I more or less agree here. The suppression of copies
doesn't cause me any worries, except on theoretical grounds.
The other suppressions do.
[...]
However, in the commercial code of my company, I was concerned
enough about this allowance to remove unused translation units
that I moved some namespace scope initialization code from one
file to another file which I knew was referenced externally.
It's a really bad thing in the standard which should be
removed. Hopefully it will be if and when we ever get dll aka
shared "object" support.
I'm not sure what you mean by "bad thing" in the standard. The
standard is simply conforming to the universal existing
practice, and in fact, leaves the entire issue "implementation
defined". (Everything concerning how you invoke the compiler is
"implementation defined". There is an implication, however, in
the statement "Library components are linked to satisfy external
references to functions and objects not defined in the current
translation." (=A72.1/9)
Sorry. I wasn't clear enough. The whole time I was referring to C++03
standard - "3.6.2 Initialization of non-local objects / 3". AFAIK: In
practice, it's basically impossible for a compiler, linker, and
implementation to delay the dynamic initialization of some namespace
scope objects past main but before an actual first use of the
translation unit - barring specific user guidance such as the creation
of a shared object. It's a token gesture at making shared objects
standard conformant.
It's a misguided gesture at making dynamic linking standard
conformant. To be conformant, an implementation must behave "as
if" everything was linked before any user written code is
executed. This automatically excludes any explicit dynamic
linking (calls to dlopen or LoadLibrary). And if implicit
dynamic linking loads all of the dependencies on program start
up, it more or less fulfills the requirement to behave "as if".
However, someone saw this as a cool allowance to
optimize away "unreferenced" but still linked translation units.
Who? I know several people who have expressed the opinion that
the current wording does allow this, but I know of no compiler
which actually exploits it.
That is the bug in the standard with which I was annoyed.
Because I was afraid of being bitten by that, I moved
a namespace scope object whose entire job was to initialize
a callback from its own cpp file to an already existing cpp
file to ensure that some broken-but-conforming linker wouldn't
optimize it away.
I use the technique you're trying to use extensively, and I've
never had any problems, either with static or dynamic
linking---neither on Unix platforms (Solaris or Linux) nor under
Windows. The important thing has always been to ensure that the
object file with the static object is part of the process: this
is done either by linking the object file explicitly, either
into the executable or into a dynamic object which is explicitly
linked.
--
James Kanze