Re: compilers, endianness and padding
On Thu, 9 May 2013 00:03:42 -0700 (PDT)
Thomas Richter <thor@math.tu-berlin.de> wrote:
(otherwise, please explain me how to serialize a pointer).
I'm sorry, but I consider this a trope. Not only is "serializing a
pointer" a solved problem in two dozen libraries since, oh, COBRA, but
ostream operator<<(ostream, char *)
has been, as you well know, defined in namespace std for 25 years.
Why do people think pointers can't be serialized?
This is the wrong place for it because the philosophy of *this*
language is a different one. It is "do not pay for what you do not
need", and I do not need it. I can write portable I/O just fine
without the help of the language. I use libraries for that.
I find it odd that
char *s = "hello";
cout << s;
works, but
struct { char *s; } s = { "hello" };
cout << s;
does not. I do not understand why we accept serialization of built-in
types, and resolutely refuse to standardize -- or even support the
standardization of -- serialization of user-defined types.
The minimum I would like to see is the ability to iterate over the
members of a structure. Suppose they were described as an array of
tuples of {type, size, constness}. Then we could serialize abstractly
along the lines of
struct { ... } foo;
for_each(members_of(foo).begin(), ... );
The compiler could readily support automatic typing of the members_of
elements and supply sufficient metadata to traverse an
inheritance/aggregation tree. These are the necessary missing
ingredients to a standard serialization library.
There need not be any cost. The metadata are required only if
referenced. Nothing prevents the optimizer from stripping it away.
Nothing prevents the compiler from segregating the metadata somewhere
such that it is not loaded into memory unless it's used.
But wait, you say. Why is serialization so important? I ask you, why
is std::string special?
When C++ was young, the liabilities of uninitilalized pointers and
null-terminated character arrays in C were widely acknowledged. C++
answered them with references (foo_t&) and std::string. The language
succeeded by answering the needs of the day.
Both language and library were designed when networks were still
strange and nonstandard, when people still paid attention to the ISO
model and SNA and X.400. Networking was a bespoke business; the
problem of transmitting a data structures from one machine to another
was hardly standardized at the operating system level, let along
between applications. Cfront appeared in 1985; the likes of CORBA not
until 1992, NCSA Mosaic in 1993. Indeed, when Java arrived in 1995
its main claim to fame other than GC was built-in networking.
Given the networks of the day (primitive), the machines of the day
(slower by 6 orders of magnitude), and the experience with C++ at the
time (roughly nil) Stroustrup & friends restricted themselves to a
single, well understood problem: std::string. To answer my own
question, std::string is special because its need was recognized in
1985.
In 2013, the need for stardardized serialization has become clear.
Dozens of incompatible serialization libraries have been written. All
are more awkward than would be necessary if they didn't lack metatdata
support from the compiler.
Who reading this list hasn't written operator<< for some user-defined
type and wearily wondered why each member had to be named
individually, each collection iterated over explicitly, and the format
of the whole structure re-invented and re-expressed, explicitly, by
hand, *again*?! And yet again for operator>>?
We spend far too much time today dealing with I/O, recreating by hand
the very metadata discarded by the compiler. With support from the
compiler, C++ could provide easy, standard, robust, efficient,
reliable I/O for user-defined types of arbritrary complexity. Until
then, we'll party on like it's 1985.
--jkl
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]