Discussion:
Controversy and debate: Uninitialized variables by default is a bug
(too old to reply)
Matthew Fioravante
2014-06-17 15:49:57 UTC
Permalink
This is going to be controversial, but lets get into it.

The fact that `int x;` creates an uninitialized integer instead of a
default initialized one is completely wrong. I consider it a major defect
in the language, a bug in the standard.

One of my favorite C++11 API's is the atomic API. The reason is that it
does the right thing when it comes to correctness vs speed. By default, the
path of least resistance is to have everything sequentially consistent
which is the safest but also slowest memory ordering. If you know what
you're doing and need some speed, you can opt to use less safe orderings.
Even better, every use of the less safe ordering is tagged right there in
the source code (without a comment)! It really doesn't get much better than
that in terms of API design. It follows Scott Meyers maxim of "Making
interfaces easy to use correctly and hard to use incorrectly" perfectly.

Initialization in C++ is the exact opposite of this. The easiest thing to
do is write bugs by forgetting to initialize things. How many of you have
spent long debugging sessions only to track the source to an uninitialized
variable? Not only that, but initialization in C++ is a horrible mess. lets
look at the list:

Default initialization
Value Initialization
Copy Initialization
Direct Initialization
Aggregate Initialization
List initialization
Reference Initialization
Constant Initialization

Do you know by memory how all of those work and their gotchas? I sure as
hell don't and I pity the novice developer who tries. Do we need this level
of complexity?

Here is a sketch one possible way we could solve this problem:

int x; //<-default initialized to 0
int x = void; //<-uninitialized, I know what I'm doing
volatile int x; //<-uninitialized, because we can't introduce
additional writes to volatile variables or break existing device driver
code.

Like the atomic API, the default action is the safe action, with options to
remove the restraints should you need it.
What I'm suggesting is that everything be initialized by default. And yes
that means all legacy code that flips the switch to use the next version of
the C++ language. If someone has a compelling performance argument for
leaving something uninitialized, the = void syntax is there for them.

What are the advantages:
1) Safe by default, if someone does a statistical survey, I'm confident
that after this change the average amount of time spent debugging C++ code
will go down.
2) Dangerous places are marked (=void) as such, bringing attention and
carefully scrutiny by the person reading code.
3) Less boilerplate code. Particularly with constructors I don't have to
write a bunch of stupid initialization code for my ints, floats, and
pointers.
4) Initialization behavior matches static and global variables. One less
"except when" for Herb Sutter to write about in GotW.

Counter arguments:
1) This will slow down everyone's programs!

No it won't. Compilers have been doing something called constant
propagation for over 20 years.

That is, this code:

int x = 0;
x = 1;

Will be optimized to this:
int x = 1;

2) This will break C compatibility!

No it won't. extern "C" code will still have the old behavior. There is no
C breakage here. The data being passed to and from C code is still the
same, regardless of whether or not it was initialized by the compiler.

3) Why do we need this? Compilers, static checkers, and debugging tools can
detect uninitialized use!

Not always, and these tools are not always available. For example valgrind
is unusable on large resource consuming code bases. Also, even if there is
a tool why am I wasting my time checking this crap? I'd rather not be able
to easily write these bugs in the first place. Fix this and one *major*
class of bugs in C++ go away forever.

4) It will break legacy code!

In some cases yes, but lets take a deeper look at the possibilities here:

There are legacy code bases with real uninitialized variable bugs in them
today. Your company probably has 1 or 2 in their large code base and
miraculously its still working fine. If all of the sudden these things get
fixed, it may change the behavior of your program, causing a "bug" in the
sense that production is now operating differently. What used to be
undefined behavior just got defined. I don't see this as a huge problem. If
you have bugs in your code they need to be fixed. Also I do not believe
this is a good enough reason to continue the subpar status quo forever.

Then there may be other cases, for example some kind of strange embedded
code or device drivers. Perhaps you instantiate an object over top of a
hardware memory address. If you are doing this, you are probably also
marking your variables as volatile, and that as I proposed above is still
uninitialized so you won't be affected.

Maybe you're doing something really funky like putting your call stack on
some special memory, and default initialization will cause additional
writes which will cause your program to fail. If you're doing this kind of
crazy low level stuff, then you should know enough to be able to fix your
code. Also you will be now annotating these instances with = void or
volatile and that has the additional benefit of saying in your code,
without a comment "*hey I'm doing some funny stuff here with initialization*
".

5) I'm so good I don't write these kinds of bugs

Congratulations, good job. Your colleagues however do write these kind of
bugs and will continue to do so until the end of time. Sometimes you may
even get to debug for them.

I really enjoy C++, for all of its warts. I believe unlike other languages
which come and go, C++ has staying power and will be around and growing for
a long time. C++ is the fastest and most versatile language on the planet.
I don't see everyone jumping ship anytime soon for a complete rewrite
language like D (sorry Andrei). We're stuck with C++, so lets make it a
better language.

Doing something like this would be huge. It would require a lot of analysis
to get right. My simple idea of =void (inspired from D, thanks Andrei) may
not work in all cases and will need to be fleshed out further.

Please now, convince if you can why this is a bad idea. Why should we
continue to inflict wasted hours of debugging sessions for these kinds of
silly easy to write bugs on the future of C++? Can you think of any
possible reason uninitialized by default is good other than "maintaining
legacy code".
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
Jonathan Coe
2014-06-17 15:53:33 UTC
Permalink
Sometimes (in embedded systems for instance) initialization cost is
considered to be significant. C++ generally follows the philosophy that you
only pay for what you need. User- or library-defined types can force
primitives to be initialized or value initialize them.

for instance:
http://www.boost.org/doc/libs/1_55_0/libs/utility/value_init.htm

Regards,

Jon
Post by Matthew Fioravante
This is going to be controversial, but lets get into it.
The fact that `int x;` creates an uninitialized integer instead of a
default initialized one is completely wrong. I consider it a major defect
in the language, a bug in the standard.
One of my favorite C++11 API's is the atomic API. The reason is that it
does the right thing when it comes to correctness vs speed. By default, the
path of least resistance is to have everything sequentially consistent
which is the safest but also slowest memory ordering. If you know what
you're doing and need some speed, you can opt to use less safe orderings.
Even better, every use of the less safe ordering is tagged right there in
the source code (without a comment)! It really doesn't get much better than
that in terms of API design. It follows Scott Meyers maxim of "Making
interfaces easy to use correctly and hard to use incorrectly" perfectly.
Initialization in C++ is the exact opposite of this. The easiest thing to
do is write bugs by forgetting to initialize things. How many of you have
spent long debugging sessions only to track the source to an uninitialized
variable? Not only that, but initialization in C++ is a horrible mess. lets
Default initialization
Value Initialization
Copy Initialization
Direct Initialization
Aggregate Initialization
List initialization
Reference Initialization
Constant Initialization
Do you know by memory how all of those work and their gotchas? I sure as
hell don't and I pity the novice developer who tries. Do we need this level
of complexity?
int x; //<-default initialized to 0
int x = void; //<-uninitialized, I know what I'm doing
volatile int x; //<-uninitialized, because we can't introduce
additional writes to volatile variables or break existing device driver
code.
Like the atomic API, the default action is the safe action, with options
to remove the restraints should you need it.
What I'm suggesting is that everything be initialized by default. And yes
that means all legacy code that flips the switch to use the next version of
the C++ language. If someone has a compelling performance argument for
leaving something uninitialized, the = void syntax is there for them.
1) Safe by default, if someone does a statistical survey, I'm confident
that after this change the average amount of time spent debugging C++ code
will go down.
2) Dangerous places are marked (=void) as such, bringing attention and
carefully scrutiny by the person reading code.
3) Less boilerplate code. Particularly with constructors I don't have to
write a bunch of stupid initialization code for my ints, floats, and
pointers.
4) Initialization behavior matches static and global variables. One less
"except when" for Herb Sutter to write about in GotW.
1) This will slow down everyone's programs!
No it won't. Compilers have been doing something called constant
propagation for over 20 years.
int x = 0;
x = 1;
int x = 1;
2) This will break C compatibility!
No it won't. extern "C" code will still have the old behavior. There is no
C breakage here. The data being passed to and from C code is still the
same, regardless of whether or not it was initialized by the compiler.
3) Why do we need this? Compilers, static checkers, and debugging tools
can detect uninitialized use!
Not always, and these tools are not always available. For example valgrind
is unusable on large resource consuming code bases. Also, even if there is
a tool why am I wasting my time checking this crap? I'd rather not be able
to easily write these bugs in the first place. Fix this and one *major*
class of bugs in C++ go away forever.
4) It will break legacy code!
There are legacy code bases with real uninitialized variable bugs in them
today. Your company probably has 1 or 2 in their large code base and
miraculously its still working fine. If all of the sudden these things get
fixed, it may change the behavior of your program, causing a "bug" in the
sense that production is now operating differently. What used to be
undefined behavior just got defined. I don't see this as a huge problem. If
you have bugs in your code they need to be fixed. Also I do not believe
this is a good enough reason to continue the subpar status quo forever.
Then there may be other cases, for example some kind of strange embedded
code or device drivers. Perhaps you instantiate an object over top of a
hardware memory address. If you are doing this, you are probably also
marking your variables as volatile, and that as I proposed above is still
uninitialized so you won't be affected.
Maybe you're doing something really funky like putting your call stack on
some special memory, and default initialization will cause additional
writes which will cause your program to fail. If you're doing this kind of
crazy low level stuff, then you should know enough to be able to fix your
code. Also you will be now annotating these instances with = void or
volatile and that has the additional benefit of saying in your code,
without a comment "*hey I'm doing some funny stuff here with
initialization*".
5) I'm so good I don't write these kinds of bugs
Congratulations, good job. Your colleagues however do write these kind of
bugs and will continue to do so until the end of time. Sometimes you may
even get to debug for them.
I really enjoy C++, for all of its warts. I believe unlike other languages
which come and go, C++ has staying power and will be around and growing for
a long time. C++ is the fastest and most versatile language on the planet.
I don't see everyone jumping ship anytime soon for a complete rewrite
language like D (sorry Andrei). We're stuck with C++, so lets make it a
better language.
Doing something like this would be huge. It would require a lot of
analysis to get right. My simple idea of =void (inspired from D, thanks
Andrei) may not work in all cases and will need to be fleshed out further.
Please now, convince if you can why this is a bad idea. Why should we
continue to inflict wasted hours of debugging sessions for these kinds of
silly easy to write bugs on the future of C++? Can you think of any
possible reason uninitialized by default is good other than "maintaining
legacy code".
--
---
You received this message because you are subscribed to the Google Groups
"ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an
Visit this group at
http://groups.google.com/a/isocpp.org/group/std-proposals/.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
Matthew Fioravante
2014-06-17 16:00:47 UTC
Permalink
Post by Jonathan Coe
Sometimes (in embedded systems for instance) initialization cost is
considered to be significant. C++ generally follows the philosophy that you
only pay for what you need. User- or library-defined types can force
primitives to be initialized or value initialize them.
The key word here is "sometimes". Sometimes initialization is expensive,
most of the time it is not or just optimized away. For those some times,
you can use =void, or boost value_init (we could have a std::noinit<T>
wrapper), or some other specialized method. As long as this method exists,
the only pay for what you need philosophy still sticks. If you find
initialization to be expensive, use the alternative method (which also
documents your intent in the code without comments).

Most of the time when people talk about initialization costs, they are
doing something like constructing a vector of objects. This initialization
cost is already in the standard because vector will initialize the objects.
Nothing I am proposing here changes that or makes it worse.
Post by Jonathan Coe
http://www.boost.org/doc/libs/1_55_0/libs/utility/value_init.htm
Regards,
Jon
Post by Matthew Fioravante
This is going to be controversial, but lets get into it.
The fact that `int x;` creates an uninitialized integer instead of a
default initialized one is completely wrong. I consider it a major defect
in the language, a bug in the standard.
One of my favorite C++11 API's is the atomic API. The reason is that it
does the right thing when it comes to correctness vs speed. By default, the
path of least resistance is to have everything sequentially consistent
which is the safest but also slowest memory ordering. If you know what
you're doing and need some speed, you can opt to use less safe orderings.
Even better, every use of the less safe ordering is tagged right there in
the source code (without a comment)! It really doesn't get much better than
that in terms of API design. It follows Scott Meyers maxim of "Making
interfaces easy to use correctly and hard to use incorrectly" perfectly.
Initialization in C++ is the exact opposite of this. The easiest thing to
do is write bugs by forgetting to initialize things. How many of you have
spent long debugging sessions only to track the source to an uninitialized
variable? Not only that, but initialization in C++ is a horrible mess. lets
Default initialization
Value Initialization
Copy Initialization
Direct Initialization
Aggregate Initialization
List initialization
Reference Initialization
Constant Initialization
Do you know by memory how all of those work and their gotchas? I sure as
hell don't and I pity the novice developer who tries. Do we need this level
of complexity?
int x; //<-default initialized to 0
int x = void; //<-uninitialized, I know what I'm doing
volatile int x; //<-uninitialized, because we can't introduce
additional writes to volatile variables or break existing device driver
code.
Like the atomic API, the default action is the safe action, with options
to remove the restraints should you need it.
What I'm suggesting is that everything be initialized by default. And yes
that means all legacy code that flips the switch to use the next version of
the C++ language. If someone has a compelling performance argument for
leaving something uninitialized, the = void syntax is there for them.
1) Safe by default, if someone does a statistical survey, I'm confident
that after this change the average amount of time spent debugging C++ code
will go down.
2) Dangerous places are marked (=void) as such, bringing attention and
carefully scrutiny by the person reading code.
3) Less boilerplate code. Particularly with constructors I don't have to
write a bunch of stupid initialization code for my ints, floats, and
pointers.
4) Initialization behavior matches static and global variables. One less
"except when" for Herb Sutter to write about in GotW.
1) This will slow down everyone's programs!
No it won't. Compilers have been doing something called constant
propagation for over 20 years.
int x = 0;
x = 1;
int x = 1;
2) This will break C compatibility!
No it won't. extern "C" code will still have the old behavior. There is
no C breakage here. The data being passed to and from C code is still the
same, regardless of whether or not it was initialized by the compiler.
3) Why do we need this? Compilers, static checkers, and debugging tools
can detect uninitialized use!
Not always, and these tools are not always available. For example
valgrind is unusable on large resource consuming code bases. Also, even if
there is a tool why am I wasting my time checking this crap? I'd rather not
be able to easily write these bugs in the first place. Fix this and one
*major* class of bugs in C++ go away forever.
4) It will break legacy code!
There are legacy code bases with real uninitialized variable bugs in them
today. Your company probably has 1 or 2 in their large code base and
miraculously its still working fine. If all of the sudden these things get
fixed, it may change the behavior of your program, causing a "bug" in the
sense that production is now operating differently. What used to be
undefined behavior just got defined. I don't see this as a huge problem. If
you have bugs in your code they need to be fixed. Also I do not believe
this is a good enough reason to continue the subpar status quo forever.
Then there may be other cases, for example some kind of strange embedded
code or device drivers. Perhaps you instantiate an object over top of a
hardware memory address. If you are doing this, you are probably also
marking your variables as volatile, and that as I proposed above is still
uninitialized so you won't be affected.
Maybe you're doing something really funky like putting your call stack on
some special memory, and default initialization will cause additional
writes which will cause your program to fail. If you're doing this kind of
crazy low level stuff, then you should know enough to be able to fix your
code. Also you will be now annotating these instances with = void or
volatile and that has the additional benefit of saying in your code,
without a comment "*hey I'm doing some funny stuff here with
initialization*".
5) I'm so good I don't write these kinds of bugs
Congratulations, good job. Your colleagues however do write these kind of
bugs and will continue to do so until the end of time. Sometimes you may
even get to debug for them.
I really enjoy C++, for all of its warts. I believe unlike other
languages which come and go, C++ has staying power and will be around and
growing for a long time. C++ is the fastest and most versatile language on
the planet. I don't see everyone jumping ship anytime soon for a complete
rewrite language like D (sorry Andrei). We're stuck with C++, so lets make
it a better language.
Doing something like this would be huge. It would require a lot of
analysis to get right. My simple idea of =void (inspired from D, thanks
Andrei) may not work in all cases and will need to be fleshed out further.
Please now, convince if you can why this is a bad idea. Why should we
continue to inflict wasted hours of debugging sessions for these kinds of
silly easy to write bugs on the future of C++? Can you think of any
possible reason uninitialized by default is good other than "maintaining
legacy code".
--
---
You received this message because you are subscribed to the Google Groups
"ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an
Visit this group at
http://groups.google.com/a/isocpp.org/group/std-proposals/.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
Nevin Liber
2014-06-17 16:02:05 UTC
Permalink
Post by Matthew Fioravante
ost of the time when people talk about initialization costs, they are
doing something like constructing a vector of objects. This initialization
cost is already in the standard because vector will initialize the objects.
Nothing I am proposing here changes that or makes it worse.
Where can we see your benchmarking code and results?
--
Nevin ":-)" Liber <mailto:***@eviloverlord.com> (847) 691-1404
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
Matthew Fioravante
2014-06-17 16:09:36 UTC
Permalink
Post by Nevin Liber
Post by Matthew Fioravante
ost of the time when people talk about initialization costs, they are
doing something like constructing a vector of objects. This initialization
cost is already in the standard because vector will initialize the objects.
Nothing I am proposing here changes that or makes it worse.
Where can we see your benchmarking code and results?
Not sure what you're asking for. Before this idea, std::vector<T> will
always initialize its T contents. After this idea it will still do the same
thing. Not sure how a benchmark is needed for that.
--
Post by Nevin Liber
691-1404
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
Nevin Liber
2014-06-17 16:12:51 UTC
Permalink
After this idea it will still do the same thing. Not sure how a benchmark
is needed for that.
You've made a bold, unsubstantiated claim this has no performance
implications, and hand wave away anyone who disagrees. This is a question
that data quite easily answer, and anyone making performance claims ought
to have it.
--
Nevin ":-)" Liber <mailto:***@eviloverlord.com> (847) 691-1404
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
Ville Voutilainen
2014-06-17 15:58:10 UTC
Permalink
Post by Matthew Fioravante
This is going to be controversial, but lets get into it.
The fact that `int x;` creates an uninitialized integer instead of a default
initialized one is completely wrong. I consider it a major defect in the
language, a bug in the standard.
Well, it's not a bug by any definition that the committee uses, since we know
about it, and it's 100% intentional.
Post by Matthew Fioravante
Please now, convince if you can why this is a bad idea. Why should we
char buf[MEGABYTE];

buf[HERE] = something;
buf[THERE] = something_else;

According to what you propose, the mere definition of buf would go
through all of that
megabyte and zero-initialize the chars.

Or perhaps you meant that arrays are an exception? What about

struct X { char buf[MEGABYTE]; };

X x;

Is this also an exception to the rule?

How many performance expectations of how much existing code do you think this
change would break?

The committee's answer to this question has always been "too many, too
much", and
I don't see that changing.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
Matthew Fioravante
2014-06-17 16:07:30 UTC
Permalink
Post by Matthew Fioravante
Post by Matthew Fioravante
This is going to be controversial, but lets get into it.
The fact that `int x;` creates an uninitialized integer instead of a
default
Post by Matthew Fioravante
initialized one is completely wrong. I consider it a major defect in the
language, a bug in the standard.
Well, it's not a bug by any definition that the committee uses, since we know
about it, and it's 100% intentional.
Post by Matthew Fioravante
Please now, convince if you can why this is a bad idea. Why should we
char buf[MEGABYTE];
Arrays are not an exception.

If buf[MEGABYTE] is a global, its already initialized to 0.

If its a class member or on the stack, you can say

char buf[MEGABYTE] = void;

to skip initialization. Otherwise it gets filled with 0s.
Post by Matthew Fioravante
buf[HERE] = something;
buf[THERE] = something_else;
According to what you propose, the mere definition of buf would go
through all of that
megabyte and zero-initialize the chars.
Or perhaps you meant that arrays are an exception? What about
struct X { char buf[MEGABYTE]; };
X x;
Is this also an exception to the rule?
Possibilities here:

struct X { char buf[MEGABYTE] = void }; //All default constructed objects
of type X will have uninitialized buffers
X x; //< buf is not initialized

//OR
struct X { char buf[MEGABYTE]; };
X x = void; //<-This particular x will not initialize its members by
default (Same as X x; now)
Post by Matthew Fioravante
How many performance expectations of how much existing code do you think this
change would break?
We would need to study this to find out.
Post by Matthew Fioravante
The committee's answer to this question has always been "too many, too
much", and
I don't see that changing.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
Ville Voutilainen
2014-06-17 16:09:17 UTC
Permalink
Post by Matthew Fioravante
Post by Ville Voutilainen
char buf[MEGABYTE];
Arrays are not an exception.
If buf[MEGABYTE] is a global, its already initialized to 0.
If its a class member or on the stack, you can say
char buf[MEGABYTE] = void;
to skip initialization. Otherwise it gets filled with 0s.
Yeah. And this sort of a difference to existing code has killed this idea
EVERY TIME.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
Matthew Fioravante
2014-06-17 16:24:29 UTC
Permalink
Post by Ville Voutilainen
Post by Matthew Fioravante
Post by Ville Voutilainen
char buf[MEGABYTE];
Arrays are not an exception.
If buf[MEGABYTE] is a global, its already initialized to 0.
If its a class member or on the stack, you can say
char buf[MEGABYTE] = void;
to skip initialization. Otherwise it gets filled with 0s.
Yeah. And this sort of a difference to existing code has killed this idea
EVERY TIME.
Why not write a conversion tool to check for instances of this?
Post by Ville Voutilainen
Post by Matthew Fioravante
After this idea it will still do the same thing. Not sure how a
benchmark is needed for that.
You've made a bold, unsubstantiated claim this has no performance
implications, and hand wave away anyone who disagrees. This is a question
that data quite easily answer, and anyone making performance claims ought
to have it.
The 2 things we are discussing (initializing aggregates by default vs
standard library container initialization behavior) are orthogonal. Do you
test the performance of std::map every time you write a file parsing
routine?

Ville's point about buf[MEGABYTE] is valid. There are real performance
implications there because the behavior changes with arrays.

Standard library containers do not behave any differently, they always
initialize their contents by default as they were designed to do in the
beginning.
Post by Ville Voutilainen
--
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
Nevin Liber
2014-06-17 16:29:22 UTC
Permalink
Post by Matthew Fioravante
Standard library containers do not behave any differently, they always
initialize their contents by default as they were designed to do in the
beginning.
No, they don't. They use the construct function in the allocator. One use
of allocators is to eliminate the cost of zero initializing large vectors.
--
Nevin ":-)" Liber <mailto:***@eviloverlord.com> (847) 691-1404
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
Matthew Fioravante
2014-06-17 16:34:52 UTC
Permalink
Any change in behavior/performance for a standard library container would
be a QoI problem. I'm not proposing any changes to the standard library
with regards to how it does or does not initialize things.
Post by Nevin Liber
Post by Matthew Fioravante
Standard library containers do not behave any differently, they always
initialize their contents by default as they were designed to do in the
beginning.
No, they don't. They use the construct function in the allocator. One
use of allocators is to eliminate the cost of zero initializing large
vectors.
--
691-1404
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
Nevin Liber
2014-06-17 15:58:12 UTC
Permalink
Post by Matthew Fioravante
Please now, convince if you can why this is a bad idea.
Because IMO the correct answer is that the default should be for requiring
users to explicitly initialize the variable, and have a way to mark it the
few times they want an uninitialized variable. All initializing to zero
does is move the problem from something that static analyzers can catch to
something they can't.

Plus, that ship has sailed with C a long, long time ago...
--
Nevin ":-)" Liber <mailto:***@eviloverlord.com> (847) 691-1404
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
Jim Porter
2014-06-17 16:20:13 UTC
Permalink
Post by Nevin Liber
Post by Matthew Fioravante
Please now, convince if you can why this is a bad idea.
Because IMO the correct answer is that the default should be for requiring
users to explicitly initialize the variable, and have a way to mark it the
few times they want an uninitialized variable. All initializing to zero
does is move the problem from something that static analyzers can catch to
something they can't.
I agree. I strongly believe that is there is a default behavior for
variable declarations with no initializer, it shouldn't initialize the
variable at all. However, I'm not convinced that there *needs* to be a
default case except for maintaining compatibility.
Post by Nevin Liber
Plus, that ship has sailed with C a long, long time ago...
I think it would be reasonable to add the option
explicit-non-initialization to the standard, e.g.

int foo; // doesn't initialize
int foo = __no_init__; // doesn't initialize
int foo = 0; // initializes

(I'm avoiding picking a real syntax for this for now.) This lets people be
explicit rather than implicit when they don't want to initialize a variable
at declaration, which would then allow compilers to emit a warning (not an
error!) if you don't do this. However, I'd hope that compiler authors would
only emit the warning when their static analyzer couldn't prove that you
always set the variable anyway. That is, the following shouldn't warn:

int func() {
int foo;
if(something)
foo = 1;
else
foo = 2;
}

- Jim
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
Magnus Fromreide
2014-06-20 20:20:26 UTC
Permalink
X-Gm-Message-State: ALoCoQl2UCOyK4mEVKs2O/jAMgZKv1ad8BE0i2F/TGwKIpYl+xX9MUxw90zIJ1L4q2L7HLeHOc3t
X-Received: by 10.152.36.226 with SMTP id t2mr526128laj.1.1403295630244;
Fri, 20 Jun 2014 13:20:30 -0700 (PDT)
X-BeenThere: std-***@isocpp.org
Received: by 10.180.37.206 with SMTP id a14ls134150wik.51.gmail; Fri, 20 Jun
2014 13:20:28 -0700 (PDT)
X-Received: by 10.194.216.136 with SMTP id oq8mr6809347wjc.33.1403295628639;
Fri, 20 Jun 2014 13:20:28 -0700 (PDT)
Received: from bacon.lysator.liu.se (bacon.lysator.liu.se. [2001:6b0:17:f0a0::ce])
by mx.google.com with ESMTPS id vk2si12576781wjc.54.2014.06.20.13.20.28
for <std-***@isocpp.org>
(version=TLSv1 cipher=RC4-SHA bits=128/128);
Fri, 20 Jun 2014 13:20:28 -0700 (PDT)
Received-SPF: none (google.com: ***@bacon.lysator.liu.se does not designate permitted sender hosts) client-ip=2001:6b0:17:f0a0::ce;
Received: from bacon.lysator.liu.se (localhost [127.0.0.1])
by bacon.lysator.liu.se (8.14.5+Sun/8.14.5) with ESMTP id s5KKKRMP000505
for <std-***@isocpp.org>; Fri, 20 Jun 2014 22:20:27 +0200 (MEST)
Received: (from ***@localhost)
by bacon.lysator.liu.se (8.14.5+Sun/8.14.5/Submit) id s5KKKRJH000504
for std-***@isocpp.org; Fri, 20 Jun 2014 22:20:27 +0200 (MEST)
Mail-Followup-To: std-***@isocpp.org
In-Reply-To: <ec6e4a5c-c6c9-4921-ac4c-***@isocpp.org>
User-Agent: Mutt/1.5.12-2006-07-14
X-Original-Sender: ***@lysator.liu.se
X-Original-Authentication-Results: mx.google.com; spf=neutral
(google.com: ***@bacon.lysator.liu.se does not designate permitted sender
hosts) smtp.mail=***@bacon.lysator.liu.se
Precedence: list
Mailing-list: list std-***@isocpp.org; contact std-proposals+***@isocpp.org
List-ID: <std-proposals.isocpp.org>
X-Google-Group-Id: 399137483710
List-Post: <http://groups.google.com/a/isocpp.org/group/std-proposals/post>, <mailto:std-***@isocpp.org>
List-Help: <http://support.google.com/a/isocpp.org/bin/topic.py?topic=25838>, <mailto:std-proposals+***@isocpp.org>
List-Archive: <http://groups.google.com/a/isocpp.org/group/std-proposals/>
List-Subscribe: <http://groups.google.com/a/isocpp.org/group/std-proposals/subscribe>,
<mailto:std-proposals+***@isocpp.org>
List-Unsubscribe: <http://groups.google.com/a/isocpp.org/group/std-proposals/subscribe>,
<mailto:googlegroups-manage+399137483710+***@googlegroups.com>
Content-Disposition: inline
Archived-At: <http://permalink.gmane.org/gmane.comp.lang.c++.isocpp.proposals/11536>
Post by Jim Porter
Post by Nevin Liber
Plus, that ship has sailed with C a long, long time ago...
I think it would be reasonable to add the option
explicit-non-initialization to the standard, e.g.
int foo; // doesn't initialize
int foo = __no_init__; // doesn't initialize
int foo = 0; // initializes
That would probably require some way to detect explicit-non-initialization
in order to support

std::vector<int> v(MEGABYTE, __no_init__); // a megabyte vector with
// unspecified content

which seems like a natural extension if explicit non-initialization is
added to the language.

/MF
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
Matthew Fioravante
2014-06-24 14:51:34 UTC
Permalink
I'll respond to all of the feedback later.
In the meantime, it looks like Scott Meyers had something to say about this
very subject in the first 10 minutes of this talk:


Post by Magnus Fromreide
Post by Jim Porter
Post by Nevin Liber
Plus, that ship has sailed with C a long, long time ago...
I think it would be reasonable to add the option
explicit-non-initialization to the standard, e.g.
int foo; // doesn't initialize
int foo = __no_init__; // doesn't initialize
int foo = 0; // initializes
That would probably require some way to detect explicit-non-initialization
in order to support
std::vector<int> v(MEGABYTE, __no_init__); // a megabyte vector with
// unspecified content
which seems like a natural extension if explicit non-initialization is
added to the language.
/MF
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
David Krauss
2014-06-30 15:52:34 UTC
Permalink
Post by Magnus Fromreide
That would probably require some way to detect explicit-non-initialization
in order to support
std::vector<int> v(MEGABYTE, __no_init__); // a megabyte vector with
// unspecified content
which seems like a natural extension if explicit non-initialization is
added to the language.
__no_init__ (or uninitialized, or whatever) could be like nullptr, a sole value of its type.

A library-only solution (with conversion functions) would even be workable, but for the fact that you cannot copy an uninitialized object.

It sounds like a nice core language extension.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
Matthew Fioravante
2014-07-21 04:00:51 UTC
Permalink
Why not just a std::noinit<T> wrapper?

std::vector<std::noinit<int>>; //Does not initialize contents on
construction

Then the non-initialization is documented and enforced by the type system.
Another option is a simple std::allocator implementation.
Post by Jim Porter
Post by Magnus Fromreide
That would probably require some way to detect
explicit-non-initialization
Post by Magnus Fromreide
in order to support
std::vector<int> v(MEGABYTE, __no_init__); // a megabyte vector with
// unspecified content
which seems like a natural extension if explicit non-initialization is
added to the language.
__no_init__ (or uninitialized, or whatever) could be like nullptr, a sole
value of its type.
A library-only solution (with conversion functions) would even be
workable, but for the fact that you cannot copy an uninitialized object.
It sounds like a nice core language extension.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
David Krauss
2014-07-21 04:21:24 UTC
Permalink
Post by Matthew Fioravante
Why not just a std::noinit<T> wrapper?
std::vector<std::noinit<int>>; //Does not initialize contents on construction
Then the non-initialization is documented and enforced by the type system.
Transparent wrappers are a can of worms.

If wrapping isn't needed, then you can already use std::aligned_storage. I mentioned this earlier in the thread.

The nice thing about a singular value std::uninitialized is that it's also guaranteed to propagate by the type system, but only to its own point of use. And, it can be used for overloading. For classes, it would generally convey the idea of "invalid until assignment or further initialization," and it would be implemented by propagating uninitialized initializers to members. A constructor overloaded on std::uninitialized_t, rather than the default constructor, would be the canonical way to write an ugly partial-initialization semantic.
Post by Matthew Fioravante
Another option is a simple std::allocator implementation.
That allocator could well be standardized. Here's an implementation I have lying around, but I don't think it was ever tested.

template< typename client >
struct default_construct_allocator : std::allocator< client > {
template< typename rebound, typename arg1, typename ... arg >
void construct( rebound * p, arg1 && a1, arg && ... a )
{ ::new ( static_cast< void * >( p ) ) rebound { std::forward< arg1 >( a1 ), std::forward< arg >( a ) ... }; }

template< typename rebound >
void construct( rebound * p )
{ ::new ( static_cast< void * >( p ) ) rebound; }

template< typename rebound >
struct rebind { typedef default_construct_allocator< rebound > other; };
};
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
David Rodríguez Ibeas
2014-07-29 13:45:29 UTC
Permalink
First problem with 'std::vector<std::noinit<T>>' is that it puts the
initialization on the type of the container. I would expect that, after
proper initialization, that vector can be used wherever a 'std::vector<T>'
can be used, but by conveying the fact that it is not initialized on
construction on the type this is blocked.

The idea of using a special value on the constructor lets this be a detail
of how the object is constructed, rather than a property of the object for
the whole lifetime.

David
Post by Matthew Fioravante
Why not just a std::noinit<T> wrapper?
std::vector<std::noinit<int>>; //Does not initialize contents on
construction
Then the non-initialization is documented and enforced by the type system.
Another option is a simple std::allocator implementation.
Post by Jim Porter
Post by Magnus Fromreide
That would probably require some way to detect
explicit-non-initialization
Post by Magnus Fromreide
in order to support
std::vector<int> v(MEGABYTE, __no_init__); // a megabyte vector with
// unspecified content
which seems like a natural extension if explicit non-initialization is
added to the language.
__no_init__ (or uninitialized, or whatever) could be like nullptr, a sole
value of its type.
A library-only solution (with conversion functions) would even be
workable, but for the fact that you cannot copy an uninitialized object.
It sounds like a nice core language extension.
--
---
You received this message because you are subscribed to the Google Groups
"ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an
Visit this group at
http://groups.google.com/a/isocpp.org/group/std-proposals/.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
Lawrence Crowl
2014-06-18 20:36:26 UTC
Permalink
Post by Nevin Liber
Post by Matthew Fioravante
Please now, convince if you can why this is a bad idea.
Because IMO the correct answer is that the default should be for requiring
users to explicitly initialize the variable, and have a way to mark it the
few times they want an uninitialized variable. All initializing to zero
does is move the problem from something that static analyzers can catch to
something they can't.
Emphasized.

If every declaration or expression has a fully-defined behavior, then, to
the compiler/runtime, no program can be wrong. Undefined behavior is your
friend. It means that your program can be detectably wrong. It helps
compilers help you find bugs.
--
Lawrence Crowl
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
Stack Machine
2014-06-17 16:05:16 UTC
Permalink
I think that both sides have some compelling arguments. How about this:
int i; // compiletime error: no initializer
int i = 0; // initialize to 0
int i = void; // ok, explicitly uninitialized
Yes, this does break backwards compatibility, but in a way that produces a
compiletime error. Conversion tools shouldn't be too hard to write either.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
Lawrence Crowl
2014-06-18 20:39:39 UTC
Permalink
I think that both sides have some compelling arguments. How about
int i; // compiletime error: no initializer
int i = 0; // initialize to 0
int i = void; // ok, explicitly uninitialized
Yes, this does break backwards compatibility, but in a way that
produces a compiletime error. Conversion tools shouldn't be too
hard to write either.
Alas, things are not quite so simple. In C, "int i;" at global
scope is a tentative definition. That is, it is a definition only
in the absence of a stronger definition. Constructs like this may
still appear in systems headers.
--
Lawrence Crowl
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
Thiago Macieira
2014-06-18 21:34:10 UTC
Permalink
Post by Lawrence Crowl
Alas, things are not quite so simple. In C, "int i;" at global
scope is a tentative definition. That is, it is a definition only
in the absence of a stronger definition. Constructs like this may
still appear in systems headers.
Only in C mode. Such a code already is a full definition in C++, since C++ does
not support "common" definitions.
--
Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
Software Architect - Intel Open Source Technology Center
PGP/GPG: 0x6EF45358; fingerprint:
E067 918B B660 DBD1 105C 966C 33F5 F005 6EF4 5358
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
Thiago Macieira
2014-06-17 16:22:19 UTC
Permalink
Post by Matthew Fioravante
1) This will slow down everyone's programs!
No it won't. Compilers have been doing something called constant
propagation for over 20 years.
int x = 0;
x = 1;
int x = 1;
Except when the compiler can't prove that it is the same and so the constant
propagation fails.

int x;
switch (otherVar) {
case 1:
x = 1;
break;
case 2:
case 256:
case 32767:
x = 2;
break;
};

The compiler doesn't know whether the four values in the switch and the only
possible values.

Now, if you write that code above and use x afterwards, modern compilers will
probably produce a warning that x might be uninitialised, so people will end
up either adding a default case or initialising x. However, that's a QoI issue
and the developer might just disable the warning because they know better.
--
Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
Software Architect - Intel Open Source Technology Center
PGP/GPG: 0x6EF45358; fingerprint:
E067 918B B660 DBD1 105C 966C 33F5 F005 6EF4 5358
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
Matthew Fioravante
2014-06-17 16:27:35 UTC
Permalink
Post by Thiago Macieira
Post by Matthew Fioravante
1) This will slow down everyone's programs!
No it won't. Compilers have been doing something called constant
propagation for over 20 years.
int x = 0;
x = 1;
int x = 1;
Except when the compiler can't prove that it is the same and so the constant
propagation fails.
int x;
switch (otherVar) {
x = 1;
break;
x = 2;
break;
};
The compiler doesn't know whether the four values in the switch and the only
possible values.
Now, if you write that code above and use x afterwards, modern compilers will
probably produce a warning that x might be uninitialised, so people will end
up either adding a default case or initialising x. However, that's a QoI issue
and the developer might just disable the warning because they know better.
If you believe this to impact performance, and want to be unsafe (in the
case that someone adds and passes in a new enum value tomorrow to your
library), you can say int x = void here.
Post by Thiago Macieira
--
Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
Software Architect - Intel Open Source Technology Center
E067 918B B660 DBD1 105C 966C 33F5 F005 6EF4 5358
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
Thiago Macieira
2014-06-17 16:59:29 UTC
Permalink
Post by Matthew Fioravante
If you believe this to impact performance, and want to be unsafe (in the
case that someone adds and passes in a new enum value tomorrow to your
library), you can say int x = void here.
If we were designing a new language with no existing codebase, I'd definitely
agree with you.

Changing C++ some 40 years after the fact (if we can include the C legacy) is
a no-go.
--
Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
Software Architect - Intel Open Source Technology Center
PGP/GPG: 0x6EF45358; fingerprint:
E067 918B B660 DBD1 105C 966C 33F5 F005 6EF4 5358
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
Klaim - Joël Lamotte
2014-06-17 17:39:36 UTC
Permalink
Post by Thiago Macieira
Post by Matthew Fioravante
If you believe this to impact performance, and want to be unsafe (in the
case that someone adds and passes in a new enum value tomorrow to your
library), you can say int x = void here.
If we were designing a new language with no existing codebase, I'd definitely
agree with you.
Changing C++ some 40 years after the fact (if we can include the C legacy) is
a no-go.
Actually, I think such a change (force the user to specify initialization
or not) could be made if
there was a big amount of uncontroversial data on issues that the current
rules make easy to get into.
Also, if there is a way to easily point these issues once the change is in
place, then why not?

Basically, I don't think the initial proposal is a good idea, but
disallowing implicit uninitialization at all, and having an explicit way to
specify uninitialization, would be good enough
for the compiler to point issues immediately, and would help code readers
too to understand the intent.
It appear to me to be more compatible with C++11 and previous C++ versions
to do it that way.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
g***@gmail.com
2014-06-18 00:01:35 UTC
Permalink
Post by Klaim - Joël Lamotte
Post by Thiago Macieira
Post by Matthew Fioravante
If you believe this to impact performance, and want to be unsafe (in the
case that someone adds and passes in a new enum value tomorrow to your
library), you can say int x = void here.
If we were designing a new language with no existing codebase, I'd definitely
agree with you.
Changing C++ some 40 years after the fact (if we can include the C legacy) is
a no-go.
Actually, I think such a change (force the user to specify initialization
or not) could be made if
there was a big amount of uncontroversial data on issues that the current
rules make easy to get into.
Also, if there is a way to easily point these issues once the change is in
place, then why not?
Basically, I don't think the initial proposal is a good idea, but
disallowing implicit uninitialization at all, and having an explicit way to
specify uninitialization, would be good enough
for the compiler to point issues immediately, and would help code readers
too to understand the intent.
It appear to me to be more compatible with C++11 and previous C++ versions
to do it that way.
I agree and think having the ability to not initialize something is
definitely a useful thing and needs it's own thread / study group. There's
lots of opportunity here for performance and clarity gains, I think.

For instance.

class Person { ... };
uninitialized Person p; // Not interesting.

template<T> class Optional { // Could simplify Optional?
uninitialized T m_obj; // More interesting.
};

uninitliazed iostream stdin, stdout, stderr; // Complex initialization of
global done later.

uninitialized int x; // I'm not sure what I want yet, it's depending on the
path take, don't warn me though.

Other types of uninitialization, I'd really like to see.
std::string s;
s.uninitialized_resize(N);
c_apI(&s[0]);

s.exact_uninitialized_resize(N); // Don't double size or anything. I just
want to store this string. / it'll never grow.
c_api(&s);


Other out there ideas:

char* p = new uninitialized Person[100];

<ironic>Guy proposes default initialization. Get's offers of even less
initialization. Only in C++... </ironic>
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
Michael McLaughlin
2014-06-18 00:33:12 UTC
Permalink
I think there's a way forward here that could improve things without
changing the status quo.

Consider the following hypothetical pseudo-proposal:

- Add a syntax to explicitly specify that a variable should not be
initialized (e.g. "int x = void; float z[100000] = void;" - why " =
void"? void is already reserved and can't legally be used like that now so
it seems like a good candidate).
- Add some language to clearly specify that the
existing C/C++03/C++11/C++14 behavior (i.e. "int x; float z[100000];" means
uninitialized) is the default behavior. Then state that a conforming
implementation can give users the option to explicitly opt-in to a
different behavior. The intent being that compiler switches (or defining
some macro or whatever the implementer wants to do) can change that, but
that the user doesn't need to do anything different to keep the existing
uninitialized behavior.

I believe that those changes would be enough to give compiler vendors the
leeway needed to do several things via switches (or macro definitions,
etc.). First, they could add a behavior where the absence of the explicit
uninitialized syntax and no compiler-provable initialization produces a
compilation error. Second, they could do the same thing except instead of
an error diagnostic it emits a warning and produces zero/nullptr
initialization. Third, they could do the same thing as the second option
except with no diagnostic.

Q. Why do we need these changes? Can't implementers do this now?

A. Not with standard C++. Without a legal syntax for explicitly specifying
that a variable should not be initialized, users have no standard way to
let the compiler know that a variable is intentionally uninitialized. The
fallback then is an implementation-defined attribute or some non-standard
behavior (e.g. a language extension).


Q. What's wrong with implementation-defined attributes?

A. Nothing for features that aren't ripe for standardization. But since
this involves vendor-neutral behavior, then unless every implementer uses
the same attribute in exactly the same way, the code will start to get ugly
and unreadable pretty quickly with all of the #ifdefs (not to mention that
there's no guarantee that they'd all use attributes and no guarantee that
things would remain stable from version to version so you'd probably have
#ifdefs even if they did just happen to use the same syntax). From my
perspective as a developer, working through an old codebase and adding in "
= void" where appropriate is time consuming but easy enough. Adding a huge
block of conditional macros to every intentionally uninitialized variable
and maintaining them over the years as new and different compilers are used
to compile that code promises to be a nightmare.


Q. So what about using a standardized attribute?

A. I think the " = void" syntax is nicer, but if using an attribute (or
something else that can be standardized) instead is what it would take
to get a consensus then I'm not opposed to it. Another benefit to using " =
void" is that maybe the ISO C folks would be willing to consider that as an
addition to C (for substantially the same reasons as given here). I don't
know what they'd make of a proposal that required attributes. [ Note: If
both the ISO C and ISO C++ committees agreed to add explicit uninitialized
variables and they both adopted the same syntax, then arguments against
this due to C-compatibility issues go away. Then it's just a matter of
legacy code and the maintainers of that code would have to opt-in to this
behavior such that even that shouldn't be a problem. They can either adopt
it at their own pace (and maybe eliminate some unknown bugs along the way)
or stick with classic syntax and ignore this feature. -- end note ]


Q. But you aren't actually proposing a standardized way to eliminate
unintentionally uninitialized variables are you?

A. You caught me; my proposal doesn't do that. It proposes a syntax for
explicit uninitialized variables along with some language that gives
implementers the leeway they need to create better tools that are still
standards-conformant. I like the three hypothetical behaviors I described
earlier (compilation error; warning + zero initialization; and zero
initialization without a diagnostic) and hope that implementers
would provide all three. Indeed a formal proposal might even include
language in a Note section that strongly encouraged implementers to
provide users a way to get each of those three behaviors. But proposing
standardizing compiler switches (or any of the other ways I can think of to
actually produce any of those behaviors while leaving the default behavior
alone)? What I propose above involves a change to the language (whether
it's " = void" or a newly standardized attribute or whatever). That
change might break C compatibility in some way that can't be coded around
(though I'm not sure that it would since it's opt-in syntax that lets
implementers enable opt-in behavior). Even without the possible break with
C, it's poking a hornet's nest. I leave it to someone braver than me to
propose standardizing compiler switches.


Q. If it doesn't propose eliminating unintentionally uninitialized
variables, why bother with it at all?

A. Regardless of whether implementers make use of it to help eliminate
unintentionally uninitialized variables, I think there is merit to letting
programmers denote that a variable is intentionally uninitialized. To me
the statement "int x = void;" expresses a programmer's intent in a way that
"int x;" does not. As well, when code consistently uses "int x =
void;" then seeing "double y;" is a pretty clear sign that the code
involving 'y' bears closer scrutiny.

In summary, eliminating the default uninitialized behavior seems to
be impractical for the foreseeable future. This alternative gives us a
chance to let programmers express their intent more clearly. It also gives
implementers (by virtue of the opt-in clause) the ability to provide
standards-conformant tools that will help programmers find and eliminate
uninitialized variable bugs, while still respecting the programmer's wishes
to not have, e.g., an array of fifty thousand floats be automatically
zero-initialized. Further, if this became part of C++, it's possible that
the Committee could eventually consider deprecating the current
initialization behavior with an aim towards eventually removing it in favor
of requiring that programmers use the " = void" syntax when they actually
desire an uninitialized variable. Not that they will or even should.
But this proposal would make that something which could eventually be
practical. In the meantime it would give programmers an elegant,
concise way to make their code more expressive.

;;;

If it wouldn't be a clear waste of everyone's time, I'm willing to turn
that into a formal proposal that can be considered seriously. I wish I had
been able to make it to Rapperswil so I could float it around a bit there
to get a sense of whether it has any chance. If anyone sees any serious
flaws in it please do let me know. If you think the idea has merit, please
feel free to let me know that as well (whether on-list or off-).

Thanks!

-Mike
Post by Klaim - Joël Lamotte
Post by Thiago Macieira
Post by Matthew Fioravante
If you believe this to impact performance, and want to be unsafe (in the
case that someone adds and passes in a new enum value tomorrow to your
library), you can say int x = void here.
If we were designing a new language with no existing codebase, I'd definitely
agree with you.
Changing C++ some 40 years after the fact (if we can include the C legacy) is
a no-go.
Actually, I think such a change (force the user to specify initialization
or not) could be made if
there was a big amount of uncontroversial data on issues that the current
rules make easy to get into.
Also, if there is a way to easily point these issues once the change is in
place, then why not?
Basically, I don't think the initial proposal is a good idea, but
disallowing implicit uninitialization at all, and having an explicit way to
specify uninitialization, would be good enough
for the compiler to point issues immediately, and would help code readers
too to understand the intent.
It appear to me to be more compatible with C++11 and previous C++ versions
to do it that way.
--
---
You received this message because you are subscribed to the Google Groups
"ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an
Visit this group at
http://groups.google.com/a/isocpp.org/group/std-proposals/.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
David Krauss
2014-06-18 00:47:45 UTC
Permalink
I think there's a way forward here that could improve things without changing the status quo.
- Add a syntax to explicitly specify that a variable should not be initialized (e.g. "int x = void; float z[100000] = void;" - why " = void"? void is already reserved and can't legally be used like that now so it seems like a good candidate).
- Add some language to clearly specify that the existing C/C++03/C++11/C++14 behavior (i.e. "int x; float z[100000];" means uninitialized) is the default behavior. Then state that a conforming implementation can give users the option to explicitly opt-in to a different behavior. The intent being that compiler switches (or defining some macro or whatever the implementer wants to do) can change that, but that the user doesn't need to do anything different to keep the existing uninitialized behavior.
New syntax isn't required to select between different conforming behaviors. An [[uninitialized]] attribute should do the trick. Let it have the effect of disabling any compiler-specific warning that a trivially-constructible object is default-initialized.

Remember that it's still legal to use undifferentiated memory from malloc as any trivially-constructible type. Your proposal protects against uninitialized variables that are declared, but not against ones from new-expressions or merely willed into existence by casts.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
Tony V E
2014-06-30 15:40:38 UTC
Permalink
Post by Michael McLaughlin
I think there's a way forward here that could improve things without
changing the status quo.
<... explicitly uninitialized...>
-Mike
I agree with this direction, and don't think anything stronger (like
forcing initialization) would ever pass. (Also note that this does NOT
interfere with valgrind, sanitizers, etc)

In general, I'm all for being explicit. I'd also appreciate a way to
explicitly say "implicit" on constructors, and 'mutable' on non-const
member functions. I review a lot of code; whenever something is implicit,
I need to question whether it was intentional or not. :-(

Tony
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
walter1234
2014-06-18 01:09:43 UTC
Permalink
IMO C++ philosophy is "don't pay for what you don't use" : initialisation
is a cost, it should be possible to express the fact you can reserve space
without initialising it;
I have encountered a situation where extraneous initialisation was a
problem (dealing with an in-order CPU with very severe pipeline and cache
hazards)

The solution is better compiler warnings.

Rust is interesting, it has safe semantics , and benefits from "every block
is an expression" so its' easier to re-arrange code to keep everything
initialised - but it doesn't guarantee that it can always match C++ for
performance. (only 'performance is as high as possible without violating
safety).

So before changing C++ to guarantee things are initialised, I would say
you'd need to copy this feature.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
David Krauss
2014-06-18 01:17:58 UTC
Permalink
IMO C++ philosophy is "don't pay for what you don't use" : initialisation is a cost, it should be possible to express the fact you can reserve space without initialising it;
std::aligned_storage does this.
I have encountered a situation where extraneous initialisation was a problem (dealing with an in-order CPU with very severe pipeline and cache hazards)
The solution is better compiler warnings.
Agreed.
Rust is interesting, it has safe semantics , and benefits from "every block is an expression" so its' easier to re-arrange code to keep everything initialised - but it doesn't guarantee that it can always match C++ for performance. (only 'performance is as high as possible without violating safety).
So before changing C++ to guarantee things are initialised, I would say you'd need to copy this feature.
I've not more than glanced at Rust, and don't plan to, so perhaps you could elaborate. Treating statements as expressions is common to many languages, but I don't see the relevance. Do you mean, rather than an if-else statement, the language prefers something more like the ternary operator (perhaps with tuple un/packing), such that it tends to keep account of the assignments and you won't forget one?
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
walter1234
2014-06-18 01:27:14 UTC
Permalink
I’ve not more than glanced at Rust, and don’t plan to, so perhaps you
could elaborate. Treating statements as expressions is common to many
languages, but I don’t see the relevance. Do you mean, rather than an
if-else statement, the language prefers something more like the ternary
operator (perhaps with tuple un/packing), such that it tends to keep
account of the assignments and you won’t forget one?
[1] you can create scope blocks with temporaries, calculate something , and
return it to assign to something in the outer scope;
[2] Rust "match" (switch on steroids) has a return value, this is extremely
versatile , given everything else match can do (destructuring and
additional 'if' guards on individual match arms) .
This of course removes the case where you assign to something within switch
arms.
[3] rust's if-else replaces the C++ ternary operator

maybe I'm imagining it, but after using Rust i'm left with the perception
that these features help you to avoid needing uninitialised variables.

One thing rust doesn't do is have a return value for loops, but I would
really like them to add that (and copy python's for...else idea).. the
language is still in flux, so its not too late for them.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
r***@gmail.com
2014-06-18 01:39:25 UTC
Permalink
I don't see how default initialization will actually prevent any bugs. If a
program reads a variable sooner than intended, or if the variable was not
assigned a value when it was intended, your program still does the wrong
thing regardless of whether the variable was initialized. The only
difference is the program behaves more predictably and therefore easier to
debug, but you can get the same predictability by compiling in debug mode.
This might even make certain bugs harder to find because a program that
would otherwise seemingly fail at random might not exhibit any symptoms
until it is run under a very specific set of conditions.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
Thiago Macieira
2014-06-18 03:17:36 UTC
Permalink
Post by r***@gmail.com
I don't see how default initialization will actually prevent any bugs. If a
program reads a variable sooner than intended, or if the variable was not
assigned a value when it was intended, your program still does the wrong
thing regardless of whether the variable was initialized. The only
difference is the program behaves more predictably and therefore easier to
debug, but you can get the same predictability by compiling in debug mode.
I actually dispute that it's easier to debug.

If you use a memory debugger like Valgrind, it will be able to point out
exactly where an uninitialised variable was used when it was uninitialised. If
it happens to be initialised to zero, Valgrind can't tell intention.

That's the same reason why you should not reset pointers to null in
destructors.
Post by r***@gmail.com
This might even make certain bugs harder to find because a program that
would otherwise seemingly fail at random might not exhibit any symptoms
until it is run under a very specific set of conditions.
--
Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
Software Architect - Intel Open Source Technology Center
PGP/GPG: 0x6EF45358; fingerprint:
E067 918B B660 DBD1 105C 966C 33F5 F005 6EF4 5358
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
walter1234
2014-06-18 06:26:55 UTC
Permalink
Ok the nice behaviour of rust is requiring that you usually create
variables by assignment of an initial expression.
I agree, silently initialising to zero would actually be a step backwards.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
Christopher Jefferson
2014-06-18 08:30:51 UTC
Permalink
Post by Matthew Fioravante
This is going to be controversial, but lets get into it.
The fact that `int x;` creates an uninitialized integer instead of a
default initialized one is completely wrong. I consider it a major defect
in the language, a bug in the standard.

If you really care about this, I would recommend figuring out how to add
this feature to clang/LLVM, and come back with benchmarks. Without those,
this is a non-starter.

Chris
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
Olaf van der Spek
2014-06-18 21:44:01 UTC
Permalink
Post by Matthew Fioravante
The fact that `int x;` creates an uninitialized integer instead of a
default initialized one is completely wrong. I consider it a major defect
in the language, a bug in the standard.
Have you requested your compiler vendor for a warning for uninitialized
variables? Shouldn't be too hard, right?
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
Krzysztof Ostrowski
2014-06-19 16:33:52 UTC
Permalink
Good point, initialisation of variables is good for "safety" (state is
known from the very beginning) but it may cost too much. Initialisation of
variables is done as in C - I think that's by C++ design.

Please have a look at the following snippet.

explicit struct S {};

typedef explicit int int_type;

int_type i; // error: explicit initialisation is required
static int_type; // OK - implicitly to 0
int i; // OK

S s; // error: explicit initialisation is required
static S s; // OK if S has default constructor, we have this already



This does not break backward compatibility and reuses "explicit" keyword to
identify types (not type instances, objects) that require explicit
initialisation.
--
Krzysztof


W dniu wtorek, 17 czerwca 2014 17:49:57 UTC+2 uÅŒytkownik Matthew Fioravante
Post by Matthew Fioravante
This is going to be controversial, but lets get into it.
The fact that `int x;` creates an uninitialized integer instead of a
default initialized one is completely wrong. I consider it a major defect
in the language, a bug in the standard.
One of my favorite C++11 API's is the atomic API. The reason is that it
does the right thing when it comes to correctness vs speed. By default, the
path of least resistance is to have everything sequentially consistent
which is the safest but also slowest memory ordering. If you know what
you're doing and need some speed, you can opt to use less safe orderings.
Even better, every use of the less safe ordering is tagged right there in
the source code (without a comment)! It really doesn't get much better than
that in terms of API design. It follows Scott Meyers maxim of "Making
interfaces easy to use correctly and hard to use incorrectly" perfectly.
Initialization in C++ is the exact opposite of this. The easiest thing to
do is write bugs by forgetting to initialize things. How many of you have
spent long debugging sessions only to track the source to an uninitialized
variable? Not only that, but initialization in C++ is a horrible mess. lets
Default initialization
Value Initialization
Copy Initialization
Direct Initialization
Aggregate Initialization
List initialization
Reference Initialization
Constant Initialization
Do you know by memory how all of those work and their gotchas? I sure as
hell don't and I pity the novice developer who tries. Do we need this level
of complexity?
int x; //<-default initialized to 0
int x = void; //<-uninitialized, I know what I'm doing
volatile int x; //<-uninitialized, because we can't introduce
additional writes to volatile variables or break existing device driver
code.
Like the atomic API, the default action is the safe action, with options
to remove the restraints should you need it.
What I'm suggesting is that everything be initialized by default. And yes
that means all legacy code that flips the switch to use the next version of
the C++ language. If someone has a compelling performance argument for
leaving something uninitialized, the = void syntax is there for them.
1) Safe by default, if someone does a statistical survey, I'm confident
that after this change the average amount of time spent debugging C++ code
will go down.
2) Dangerous places are marked (=void) as such, bringing attention and
carefully scrutiny by the person reading code.
3) Less boilerplate code. Particularly with constructors I don't have to
write a bunch of stupid initialization code for my ints, floats, and
pointers.
4) Initialization behavior matches static and global variables. One less
"except when" for Herb Sutter to write about in GotW.
1) This will slow down everyone's programs!
No it won't. Compilers have been doing something called constant
propagation for over 20 years.
int x = 0;
x = 1;
int x = 1;
2) This will break C compatibility!
No it won't. extern "C" code will still have the old behavior. There is no
C breakage here. The data being passed to and from C code is still the
same, regardless of whether or not it was initialized by the compiler.
3) Why do we need this? Compilers, static checkers, and debugging tools
can detect uninitialized use!
Not always, and these tools are not always available. For example valgrind
is unusable on large resource consuming code bases. Also, even if there is
a tool why am I wasting my time checking this crap? I'd rather not be able
to easily write these bugs in the first place. Fix this and one *major*
class of bugs in C++ go away forever.
4) It will break legacy code!
There are legacy code bases with real uninitialized variable bugs in them
today. Your company probably has 1 or 2 in their large code base and
miraculously its still working fine. If all of the sudden these things get
fixed, it may change the behavior of your program, causing a "bug" in the
sense that production is now operating differently. What used to be
undefined behavior just got defined. I don't see this as a huge problem. If
you have bugs in your code they need to be fixed. Also I do not believe
this is a good enough reason to continue the subpar status quo forever.
Then there may be other cases, for example some kind of strange embedded
code or device drivers. Perhaps you instantiate an object over top of a
hardware memory address. If you are doing this, you are probably also
marking your variables as volatile, and that as I proposed above is still
uninitialized so you won't be affected.
Maybe you're doing something really funky like putting your call stack on
some special memory, and default initialization will cause additional
writes which will cause your program to fail. If you're doing this kind of
crazy low level stuff, then you should know enough to be able to fix your
code. Also you will be now annotating these instances with = void or
volatile and that has the additional benefit of saying in your code,
without a comment "*hey I'm doing some funny stuff here with
initialization*".
5) I'm so good I don't write these kinds of bugs
Congratulations, good job. Your colleagues however do write these kind of
bugs and will continue to do so until the end of time. Sometimes you may
even get to debug for them.
I really enjoy C++, for all of its warts. I believe unlike other languages
which come and go, C++ has staying power and will be around and growing for
a long time. C++ is the fastest and most versatile language on the planet.
I don't see everyone jumping ship anytime soon for a complete rewrite
language like D (sorry Andrei). We're stuck with C++, so lets make it a
better language.
Doing something like this would be huge. It would require a lot of
analysis to get right. My simple idea of =void (inspired from D, thanks
Andrei) may not work in all cases and will need to be fleshed out further.
Please now, convince if you can why this is a bad idea. Why should we
continue to inflict wasted hours of debugging sessions for these kinds of
silly easy to write bugs on the future of C++? Can you think of any
possible reason uninitialized by default is good other than "maintaining
legacy code".
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
Continue reading on narkive:
Loading...