Michael said:
Hi all
We all know that C++ is a cleverly conceived multi-paradigm language that
sacrifices very little in efficiency for what it delivers in terms of
type-safety, encapsulation and generic behaviour.
What I want to ask here is - what are the features that people most dislike
about it i.e. that: [...]
- make using or producing libraries inconvenient
Producing library is feasible in C++ but requires discipline and more
coding than it should be necessary.
I think that criticisims are totally pointless without an explanation
on "how to fix it", so, I'll give ways to fix it (My ideas are probably
not flawless, so feedback is welcome).
First, an extensible C++ library has to use, very often, the Pimpl
idiom (i.e. the class contains a pointer to the implementation's data
structure, and then, remains binary compatible even if new private
non-static data members are added or removed).
There is, a space & runtime overhead, that's why, even if the ISO
standard is written such as an implementation is allowed implement such
idiom automatically (i.e. for all classes having non-trivial
constructor or destructor), no sensible implementation would ever do
that. Furthermore such C++ implementation would not be binary
compatible with others.
That's why a "pimpl" specifier would ease library writing:
Here is how it would work:
The pimpl specifier would be used in class definition:
class __pimpl Class1 {
public:
void Func1();
protected:
virtual void Func2();
};
Instead of requiring that all definitions of the same class have the
same definition (including all private members), a __pimpl class could
be defined with missing members (except virtual functions for whom it
would be mandatory to define them all).
Thus, it would allow the library to expose only public and protected
members to users (and no private members).
Furthermore, it would also allow the library to add new members without
changing the ABI.
Constructors of __pimpl classes may launch std::bad_alloc exceptions
(even if the user-defined constructor doesn't seem throw anything).
Perhaps, it would be possible to allow one to define a __pimpl class
without all virtual members, but only a common starting sequence with
the true definition of the class.
In that case, for binary compatibility, it would require that vtables
(if it is the way virtual functions are implemented) for each class are
built from the vtable of the base class, whose size would be stored
somewhere in the vtable, and thus, allowing the copy of "unknown
pointer to functions of the vtable" from the base vtable to the derived
vtable.
So, it is probably complex to implement, but if it is well done, it
would probably really ease the conception of libraries.
Another problem when producing libraries (but that is not a language
issue, it is an implementation issue) is the fact that on the
IA-32/Win32 platform (which is widely used), there is no well-defined
ABI, and thus, linking C++ libraries of one compiler with libraries of
others is a real pain.
It can require a compilation of the source code of the library, which
is a bad thing, because, if the library is large, a user may have twice
the memory overhead of the library if he uses two different programs,
written with two different compilers, but using the same library,
compiled once for each compiler.
That's why, it could be wise for a C++ library writer, to write a C++
library, and then, a C interface to this C++ library, and finally, a
small C++ wrapper around this C interface, designed to be statically
linked to C++ programs which use this library.
On the GNU/Linux platform, there is a well-defined unique ABI, which
evolved around version 3, but is now quite stable.
I hope that in a near future, ABI compatibility will not be a problem
under x86-64 architecture under Windows.
This point is not at all a criticism of the C++ standard comittee. The
ABI is not a matter of the WG21, it is a platform-specific matter which
should be used by a platform-specific authority or consortium (i.e.
intel+compiler vendors for IA-32).