About adoption of implicit zero initialisation of POD types in theC++ standard

I

Ioannis Vranos

What argument can be against implicit zero initialisation of all POD types in all situations, being adopted in
the C++ standard, when there is no explicit initialisation provided by the programmer?



--
Ioannis A. Vranos

C95 / C++03 Developer

http://www.cpp-software.net
 
R

red floyd

Ioannis said:
What argument can be against implicit zero initialisation of all POD
types in all situations, being adopted in the C++ standard, when there
is no explicit initialisation provided by the programmer?

1. You don't pay for what you don't use.
2. C compatibility.
 
B

Bo Persson

Ioannis said:
What argument can be against implicit zero initialisation of all
POD types in all situations, being adopted in the C++ standard,
when there is no explicit initialisation provided by the
programmer?

You don't pay for what you don't use.

If C++ had initialization for all C style data, the net would be full
of benchmarks "proving" that C++ is slow and bloated.



Bo Persson
 
K

Kai-Uwe Bux

Bo said:
You don't pay for what you don't use.

If C++ had initialization for all C style data, the net would be full
of benchmarks "proving" that C++ is slow and bloated.

I doubt that. If the initial value of the variable is not used (which it
shouldn't in the case of an uninitialized variable), in the vast majority
of cases the optimizer of the compiler will be able to detect that an can
optimize away the initialization. If the initial value is used, then you
only pay for what you use :)


Best

Kai-Uwe Bux
 
I

Ioannis Vranos

What about requiring all compilers provide a specific compiler switch for zero-itinialisation of all POD
types, or a specific #pragma directive?
 
B

Bo Persson

Ioannis said:
What about requiring all compilers provide a specific compiler
switch for zero-itinialisation of all POD types, or a specific
#pragma directive?

The standard doesn't require any compiler switches. In fact, it
doesn't even require the use of a compiler - only an "implementation"
of the language.

The original (=current) standard made a huge effort to only define ONE
language, which everyone should implement. That's the general idea of
having a standard - ONE standard. Not a set of features you can pick
and choose from.

On the other hand, the upcoming standard has some "conditionally
supported" features. Perhaps this could have been one of those?



Bo Persson
 
P

peter koch

I doubt that. If the initial value of the variable is not used (which it
shouldn't in the case of an uninitialized variable), in the vast majority
of cases the optimizer of the compiler will be able to detect that an can
optimize away the initialization. If the initial value is used, then you
only pay for what you use :)

Maybe today, but that was not the case when C++ was born. I vaguely
remember that performance was the explicit argument by Stroustrup in
one of his writings - perhaps in a direct porting of C-code. But I
have no reference for this, and it could be a slip of my mind.

/Peter
 
P

peter koch

The standard doesn't require any compiler switches. In fact, it
doesn't even require the use of a compiler - only an "implementation"
of the language.

The original (=current) standard made a huge effort to only define ONE
language, which everyone should implement. That's the general idea of
having a standard - ONE standard. Not a set of features you can pick
and choose from.

On the other hand, the upcoming standard has some "conditionally
supported" features. Perhaps this could have been one of those?

On the third hand why make such a fuss about it. It should be built
into the cortex of every C++ programmer, that every variable is
initialised on first use. Writing int i should cause a slight sweat to
occur, making you initialise i right away or at least in the very next
sentence.

/Peter
 
I

Ioannis Vranos

peter said:
On the third hand why make such a fuss about it. It should be built
into the cortex of every C++ programmer, that every variable is
initialised on first use. Writing int i should cause a slight sweat to
occur, making you initialise i right away or at least in the very next
sentence.

/Peter


What about oversights? This is the way bugs can be introduced, and this is the problem the initialisation
checks of POD types aim to solve.


--
Ioannis A. Vranos

C95 / C++03 Developer

http://www.cpp-software.net
 
I

Ioannis Vranos

Ioannis said:
What about oversights? This is the way bugs can be introduced, and this
is the problem the initialisation checks of POD types aim to solve.


Perhaps the best solution to this, is not zero-initialisation, but compiler errors, when POD types are not
initialised.


--
Ioannis A. Vranos

C95 / C++03 Developer

http://www.cpp-software.net
 
J

James Kanze

I recall reading that an always-initialize-everything model
was tried in Java, and rejected specifically because it had a
serious impact on performance. Five minutes of Googling do
not turn up anything I can cite for that, though.
The Java solution is for the compiler to perform static
analysis, and generate a diagnostic if the value of any local
variable is used without prior initialization. In C++, this
is a QoI issue; in g++, for example, the flag -Wuninitialized
(enabled by -Wall) enables similar behavior.

It's a bit more complicated than that. "Objects" in Java (using
the Java definition of an object) are initialized to 0. It's
only local variables which aren't, and the reason can't be
performance---if the compiler can determine that the variable is
assigned to before being written (required at present to
determine whether the program is legal), it could easily skip
the 0 initialization, even if the standard said otherwise.
 
J

James Kanze

Maybe today, but that was not the case when C++ was born. I
vaguely remember that performance was the explicit argument by
Stroustrup in one of his writings - perhaps in a direct
porting of C-code. But I have no reference for this, and it
could be a slip of my mind.

Performance was the motivation in C. Today, any compiler worth
its salt could optimize it out most of the time, but if I'm not
mistaken, the original C compiler fit in 16KB, and there's a
serious limit to how much intelligence you can build into 16KB.

C++ just took over the C rules, without really asking any
questions.
 
J

James Kanze

peter koch wrote:
What about oversights? This is the way bugs can be introduced,
and this is the problem the initialisation checks of POD types
aim to solve.

One of the motivations (not the only one, I think) for allowing
variables to be defined anywhere, instead of just at the top of
the block, is that it eliminates almost all cases where you
might want to declare a variable without initializing it. The
results are that in C++, the lack of an initializer sticks out:
it simply doesn't get through code review.
 
J

James Kanze

Mandating such a check would break an awful lot of existing
code.

Only code that was already broken.
Even initializing previously pseudo-random memory can cause
devastating soft errors, e.g. the Debian/Valgrind/OpenSSL
fiasco.

If I understand correctly, the code in question depended on some
sort of random initialization of the data in order to
"randomize" some value. This rates as one of the most stupid
techniques I can think of. If you need a random value, there
are well established procedures for getting one. (Under Linux,
I'll seed a random number generator with values read from
/dev/random, and use it.)
Basically, peter koch is right about this. Any uninitialized
variable should give rise to perspiration.

The whole point of the "error initialization" is to increase the
chances of testing finding the use of the uninitialized value.
IMHO, even non-const variables should have a darned good
reason for not being const, and that reason usually ought to
be commented. (The obvious exception is a loop index.)

The obvious exception is anything that is going to modified:).
 
I

Ioannis Vranos

blargg said:
struct X { int i, j; };

void f( X* );

int g()
{
X x;

Here the implementation would issue the diagnostic.

f( &x ); // should compiler issue diagnostic?

Not here.
return x.i; // should compiler issue diagnostic?

Not here:

}

Consider possible implementations of f, in another compilation unit:

void f( X* x )
{
x->i = 1;
}


Speaking strictly, any uninitialised POD type would issue a diagnostic, so the function definition becomes:

void f( X* x= something ) // It passes the initialisation check
{
x->i = 1;
}


void f( X* x ) // Given the above, we would get a diagnostic here
{
x->i++;
}

(and your lines still exceed 80 characters by a longshot)


We have large monitor resolutions these days. Are you using some DOS newsgroup reader?



--
Ioannis A. Vranos

C95 / C++03 Developer

http://www.cpp-software.net
 
I

Ioannis Vranos

Jeff said:
If you break your lines at something greater
than
about 72 characters, many mail clients will
break
them again. The result is jagged lines that
are
aesthetically displeasing. 80 columns is
the
standard for source code files, but on
usenet
72 is really the maximum you should ever
use
(if you care about your readers'
experience),
and prefer 68 where feasible.

Re. the large monitor resolutions, not all of us have the eyesight to
squint at a bunch of tiny fonts. Please, just follow the conventions,
and we'll all get along fine.


72 characters ain't enough these days. I have set my newsgroup reader to 110 characters, which is also
relatively limited.



--
Ioannis A. Vranos

C95 / C++03 Developer

http://www.cpp-software.net
 
B

Bo Persson

blargg said:
struct X { int i, j; };

void f( X* );

int g()
{
X x;
f( &x ); // should compiler issue diagnostic?
return x.i; // should compiler issue diagnostic?
}

This is where a C++ developer starts to sweat, because she is forced
to interface with this old C style code.

In real C++ it would at least be

X f();

const X x = f();


(Using silly names X, x, and f to protect the guilty).



Bo Persson
 
H

highegg

What argument can be against implicit zero initialisation of all POD types in all situations, being adopted in
the C++ standard, when there is no explicit initialisation provided by the programmer?

--
Ioannis A. Vranos

C95 / C++03 Developer

http://www.cpp-software.net

Here's a specific practical concern:
It is not always desirable to initialize at allocation.
For instance, GNU Octave uses its Array class as a base for array
manipulation. It would be great to rebase the class on STL vector (to
take advantage of its automatic memory allocation, optional bounds
checking etc), but the primary obstacle is that there is no way you
can get an uninitialized vector, or, more precisely, a valid pointer
to it's uninitialized data (if you call reserve(), then it actually
works, but it's not guaranteed).
There are many instances within Octave where you allocate the memory
for an external library (BLAS, LAPACK, FFTW etc) which is supposed to
initialize it. Of course there is not even the slightest hope a
compiler can optimize out the redundant initialization in such a case
(which would occur if POD types were always initialized), because it
simply can't tell whether the external routine needs it. The impact is
usually quite small but measurable, sometimes negligible, sometimes
noticeable.
The only workaround left would be to use malloc rather than new, which
is certainly possible but brings all sorts of secondary problems.
 
J

James Kanze

Thought that was what I said...

Yes, but the general discussion (concerning C++) seemed broader,
at least to me. In Java, local variables are either pointers or
basic types; in C++, you have a lot more possibilities, and
"default initialization" can be a lot more complicated.
Not so. To run on the JVM, you have to make it past the Java
byte-code verifier. If the verifier required all local
variables to be initialized before access, then compilers
could not elide such initialization, even if they knew it were
safe to do so. The designers of Java made a conscious
decision not impose such a requirement, for reasons of
performance IIRC.

I don't know what the motivation of the Java designers was. All
I know was that performance doesn't make sense as a motivation
(which doesn't mean that it wasn't the motivation). Had the
designers required zero initialization, and dropped the
requirements for definite assignment, the compilers could have
generated exactly the same code as they do today---if your code
met the requirements of definite assignment, then the compiler
could detect it (since it is required today to detect it), and
drop the zero initialization. If your code didn't, then
according to today's rules, you would have to add an artificial
initialization, which shouldn't cost anything less (and could
cost more) than the compiler generated zero initialization. If
there is any difference in performance (and in most cases, I
don't think there will be), then requiring zero initialization
by the compiler will be faster than requiring definite
assignment.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top