Topic: n1496 (was: My top five most annoying things about C++)
Author: 6805b3x001@sneakemail.com (Davide Bolcioni)
Date: Wed, 26 May 2004 02:46:35 +0000 (UTC) Raw View
Niall Douglas ha scritto:
> On Sun, 23 May 2004 00:18:04 +0000 (UTC), Davide Bolcioni wrote:
>> the notion that shared libraries are
>> not something which should concern the language, only the linker, made
>> my job exceedingly easier.
>
>
> Sure, the Unix method makes your job easier to produce something which
> functions. However as anyone who has ever compared real-world
> application performance between Windows and Unix realises, Unix GUI
> applications just go slower - and I was even comparing two applications
> both using Qt.
I cannot comment on that, as my exposure to Qt was limited; my personal
impression on the old Athlon 700 I'm currently using is that Linux is
perceptibly faster, so your mileage may vary.
> If you go the Unix route, code *quality* suffers because it's much
> easier for the programmer to be lazy. If you go the Windows route, you
> get as perfect quality as you can for free with slightly more work. You
> already know which I prefer but I'll elaborate below.
I disagree, see below.
>>> BTW in N1496 appendix item 4 I can confirm that the Unix mechanism
>>> cannot be implemented on Windows.
>>
>> Given the time scale expected of C++0x, maybe the right question is
>> whether it is implementable for .NET ?
>
> I personally feel that when producing language standards as with any
> standard, the format should be big release, then point 1 release and
> point 2 release with point 2 released as the next big release is in
> preparation. ISO C++ has not followed this, much to its detriment :(
Point release or major release, it is due in a few years; I expect Win32
to be legacy by then, in the sense Win16 was, and that was the point of
my remark. We might be saddling C++0x with a solution for a problem
which solved itself, and leave it unable to express a solution for a
real problem of its time. Furthermore, we have C99 which is similarly
silent on the matter and will be for a few more years.
> Now we have most major compilers nearly complying with the standard ...
[cut]
Interesting points, each probably deserves its own thread so I'll not
elaborate here.
>> This should be of interest only to people implementing a linker, in my
>> opinion.
>
> Though I cannot speak for them, I cannot see Microsoft up-ending the
> Windows DLL mechanism just for ISO C++ compliance. DLL's are absolute
> core to Windows because unlike Unix it was designed from the beginning
> with them in mind.
I agree this is unlikely. Any such matter would be addressed by the
compiler, as they're now.
> If the ISO C++ spec adopts a mechanism incompatible
> with Win32, then that feature will likely be ignored on the vast
> majority of the world's computers.
The C++ standard currently ignores this peculiar behavior of a widespread
platform and this has not hindered its success on said platform; the
problem is not "C++ does not work on Windows DLLs" so I see no need to
solve that. Unless I mistake your arguments, the problem is "the Unix
implementation is slow".
>> In other words: we don't tell the programmer how the program will be
>> cobbled together, he had better make sure it works anyway. Guidelines as
>> to which tricks not to pull in order to not have things break
>> unexpectedly would be really welcome and in my humble opinion belong in
>> a language standard: FORTRAN got much mileage from its rules for common
>> variable access, for example.
>
> The trouble with this approach is that it produces sub-optimal code. If
> the compiler cannot know if a symbol is local to this DSO/DLL or not, it
> must assume the worst and run *every* *single* *access* through an
> indirection lookup. This is why code compiled with GCC using -fPIC is
> markedly slower than code compiled without and it's also more bloated.
This might sound blunt, but it is probably a problem with GCC. If I
recall my education correctly, what you plan to achieve goes under the
name of "whole program optimization"; in other words, "gcc -c" might
produce an "unfinished" object file where this choice of access is
deferred, to be resolved when "gcc" is invoked for the final link step
just before handling .o files to the linker (nobody said you have to
give the linker exactly the same .o files you started with). Since the
decisions in this step are C++ specific, it is the compiler's job,
not the linker's.
> This is partially where the speed & size differential between MSVC & GCC
> compiled binaries comes from. The trouble with "default shared" is that
> it encourages laziness - most programmers will do the minimum to get a
> working application and then stop. If it's "default private" then
> programmers must add the extra annotation to even reach a working binary
> - which is good, because code quality improves substantially.
In C, to hide a symbol you make it static. In C++ we have the unnamed
namespace and access specifiers for classes; this might or might not
be enough to provide the information you need for faster binaries, so
it might prove helpful to address this in the standard along the lines
of "if you do such and such, the translator might be forced to assume
that and produce underperforming code".
In other words, C/C++ programmers already take a visibility decision in
the code, using the language-provided means which the underlying
implementation is required to support.
> I also feel that whether something is visible outside its DSO/DLL is
> part of its API spec and thus interface contract. If you disagree with
> this, consider how public/protected/private relate to class design and
> note that similar logic applies to both.
It seems to me that you are unwilling to abstract from the concrete
implementation; if what you're after is a further layer of
modularization, you might want to research "module" concepts such as
those found in Modula languages or the "package" concept of Java.
Suppose C++ introduced class support by extending the C function syntax
like this:
void f() public class the_class_f_is_public_member_of { ... }
thus achieving what we might call "piecemeal object orientation"; in my
view, your proposal parallels the above by introducing "piecemeal
modularization". Actually, this is a problem with N1496 too.
>> On the contrary, I suggest leaving the language as it stands; just
>> acknowledge that shared libraries are a reality of current
>> implementations and might impose a series of restrictions which should
>> be observed by the programmer.
>
> The "stick head in sand" approach is only useful when a technology is
> brand new and the consequences of misapplying it may be dangerous.
> Shared libraries have been in widespread use for fifteen years - we know
> them well enough now that not acting just makes things worse.
I am not suggesting that the issue should be ignored; it is my point of view
that a specific syntactic construct to address it on a symbol by symbol
basis is inappropriate. A "modules for C++" proposal might be a more
appropriate solution for your problem; improving the compiler might also
provide most of the benefits you're after, and rephrasing the standard
to address the issue explicitly might also help a lot.
Please note that this is as much an objection to N1496 in its present
form as to the choice of making "hidden" the default visibility. In
fact, on a second reading of N1496 it seems to me that the missing
term for "linkage unit" which troubles the author might be "module".
Thank you for your attention,
Davide Bolcioni
--
Linux - the choice of a GNU generation.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: s_googlegroups@nedprod.com (Niall Douglas)
Date: Thu, 27 May 2004 03:26:12 +0000 (UTC) Raw View
On Wed, 26 May 2004 02:46:35 +0000 (UTC), Davide Bolcioni
<6805b3x001@sneakemail.com> wrote:
>> The trouble with this approach is that it produces sub-optimal code.
>> If the compiler cannot know if a symbol is local to this DSO/DLL or
>> not, it must assume the worst and run *every* *single* *access* through
>> an indirection lookup. This is why code compiled with GCC using -fPIC
>> is markedly slower than code compiled without and it's also more
>> bloated.
>
> This might sound blunt, but it is probably a problem with GCC. If I
> recall my education correctly, what you plan to achieve goes under the
> name of "whole program optimization"; in other words, "gcc -c" might
> produce an "unfinished" object file where this choice of access is
> deferred, to be resolved when "gcc" is invoked for the final link step
> just before handling .o files to the linker (nobody said you have to
> give the linker exactly the same .o files you started with). Since the
> decisions in this step are C++ specific, it is the compiler's job,
> not the linker's.
Not exactly. How ELF does shared libraries means that the app can load a
shared library and symbols from that can overwrite symbols currently
defined eg; printf() calls one implementation before and then calls a
different one thereafter. This requires the compiler to always have at
least the equivalent overhead of a virtual function call. Even with WPO
you can't elide this - to do so breaks things unless you assume no new
libraries will be loaded.
Note that for every symbol which is available outside its DSO, a
particularly expensive form of relocation must also be performed at load
time which on all implementations I know of is quadratic to symbol number.
See Ulrich Drepper's "How to write shared libraries".
>> This is partially where the speed & size differential between MSVC &
>> GCC compiled binaries comes from. The trouble with "default shared" is
>> that it encourages laziness - most programmers will do the minimum to
>> get a working application and then stop. If it's "default private" then
>> programmers must add the extra annotation to even reach a working
>> binary - which is good, because code quality improves substantially.
>
> In C, to hide a symbol you make it static. In C++ we have the unnamed
> namespace and access specifiers for classes; this might or might not
> be enough to provide the information you need for faster binaries, so
> it might prove helpful to address this in the standard along the lines
> of "if you do such and such, the translator might be forced to assume
> that and produce underperforming code".
>
> In other words, C/C++ programmers already take a visibility decision in
> the code, using the language-provided means which the underlying
> implementation is required to support.
No you're wrong here. A static symbol is indeed hidden in that it cannot
be directly referenced outside its compiland. This is not true for the
contents of unnamed namespaces - they merely add extra mangling to the
symbol which actually makes the problem worse (longer load & linking times
and more code bloat). Why don't unnamed namespaces hide their contents?
Because "export" causes searching of unnamed namespaces outside its
compiland!
Despite the C++ standard saying that static variable and function
declarations are deprecated, they still produce better quality code on
current compilers. I personally use them a lot.
>> I also feel that whether something is visible outside its DSO/DLL is
>> part of its API spec and thus interface contract. If you disagree with
>> this, consider how public/protected/private relate to class design and
>> note that similar logic applies to both.
>
> It seems to me that you are unwilling to abstract from the concrete
> implementation; if what you're after is a further layer of
> modularization, you might want to research "module" concepts such as
> those found in Modula languages or the "package" concept of Java.
Unwilling is unfair - incapable is probably more accurate. I either see
things in very low level terms or far too abstract (eg; an abstract
description of a program seems incomplete to me without including a
description of its programmers and users and cultural & societal context).
I view DLLs/DSOs as as fundamental mechanism of compartmentalising code as
classes. But anyone who likes OO won't agree with me because to an OO mind
such divisions are not considered important (and therefore SHOULDN'T be
important). This kind of mental blinkering is precisely why I don't like
OO - it encourages bad practice.
>> The "stick head in sand" approach is only useful when a technology is
>> brand new and the consequences of misapplying it may be dangerous.
>> Shared libraries have been in widespread use for fifteen years - we
>> know them well enough now that not acting just makes things worse.
>
> I am not suggesting that the issue should be ignored; it is my point of
> view
> that a specific syntactic construct to address it on a symbol by symbol
> basis is inappropriate. A "modules for C++" proposal might be a more
> appropriate solution for your problem; improving the compiler might also
> provide most of the benefits you're after, and rephrasing the standard
> to address the issue explicitly might also help a lot.
No I'd be against modules like say python does them (which is what I think
you're proposing). But why am I? I'm going entirely on gut reaction here -
somehow it seems ill-suited to a static & compiled language - I guess I'm
inferring that because I've only seen module systems on dynamic languages
(I mean here languages which perform some or all of their language
processing at run-time eg; objective C) that therefore there must be a
reason why they don't work so well for a language like C++. Also I like
how right now things can be subdivided one way at the source level (via
namespaces) but a totally different way at binary level - to me, this ADDS
value through intuitiveness.
If you could show me more proposed syntax, I could say a lot more. While
I'm initially negative, I could be very easily swayed as TBH I don't have
enough experience of what you propose would mean.
Cheers,
Niall
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]