Live data from Hacker News

Initialization in C++ is Seriously Bonkers

mikelui.io

111–120 of 130 posts

Re: Initialization in C++ is Seriously Bonkers

#111
post #110

Earlier quoted context omitted.

"Any C programmer worth anything knows that this initializes i to an indeterminate value. This is wrong. Reading the variable does not simply give you an indeterminate value, it gives undefined behaviour" Undefined behavior in the technical sense is not acceptable in a language at all, let alone a feature. If you take the idea of undefined behavior seriously, then it is valid to blow up the world in response to an er…

>If you take the idea of undefined behavior seriously, then it is valid to blow up the world in response to an error and the compiler cannot protect you That's not its job. The compiler cannot protect you from everything. (You shouldn't be using a computer that has the ability to blow up the world.) The compiler merely translates code from language A into language B. If you pass it some code in some third language wh…

> That's not its job. The compiler cannot protect you from everything.

The compiler can protect us from many things, such as uninitialised variables. It’s just that we choose to define the semantics of the C compiler such that it doesn’t.

Also I don’t think GP meant literally, physically destroy the world. It was a metaphor for catastrophic consequences of program misbehaviour. They meant that literally anything could happen, having dire consequences for reliability and security.

Re: Initialization in C++ is Seriously Bonkers

#112
post #5

In my view this author falls into the camp of people calling C++ a mess because it gives them too much control when they ask for it. One of his examples which he calls "The Abyss": #include struct A { A(std::initializer_list l) : i(2) {} A(int i = 1) : i(i) {} int i; }; int main() { A a1; A a2{}; A a3(3); A a4 = {5}; A a5{4, 3, 2}; std::cout which outputs: 1 1 3 2 2 he claims to be mysterious but is actually pretty r…

> An empty initializer list should reasonably behave like a default constructor

True. But an empty initializer list should also behave like, you know, the constructor which uses an initializer list. C++ is in the unfortunate position of having to choose one behaviour or the other. Either choice is reasonable, but both can be confusing.

Re: Initialization in C++ is Seriously Bonkers

#113

Earlier quoted context omitted.

Why not teach rust?

I can think of at least 3 reasons! 1) I don’t control the curriculum. 2) I’m pretty sure no one knows it well enough to teach. 3) Rust’s ecosystem and adoption is still too small for being taught as an engineering tool and for delivering employment opportunities to students. I personally like rust and hope it does well. I see it somewhat orthogonal to both C and C++

I’m pretty sure it’s not orthogonal. The goal is to replace both of these languages in the next 10+ years.

Re: Initialization in C++ is Seriously Bonkers

#114
post #70

Earlier quoted context omitted.

> The reason that stack variables are UNinitialized is (contra the article which thinks it's because the programmer didn't put an initializer in the source code) that memory is on the stack, which is allocated internal to your program and in practice was used previously by some other call for some other purpose. It is because the programmer didn't put an initializer into the source code. That's how the language is de…

You're not wrong, but I think this is a case where knowing the reason for the rules is easier than remembering the actual rules. This is just from personal experience, but for me, remembering what is and isn't initialized in C++ seemed completely arbitrary and insane until I learned more about linking and process startup. YMMV of course.

But if you remember the underlying reason you might think that using uninitialized variables gives just gives you an arbitrary value. That's not true, it's UB. The compiler can do whatever it wants if it can prove that you read an uninitialized variable.

Re: Initialization in C++ is Seriously Bonkers

#115
post #70

Earlier quoted context omitted.

You're not wrong, but I think this is a case where knowing the reason for the rules is easier than remembering the actual rules. This is just from personal experience, but for me, remembering what is and isn't initialized in C++ seemed completely arbitrary and insane until I learned more about linking and process startup. YMMV of course.

But if you remember the underlying reason you might think that using uninitialized variables gives just gives you an arbitrary value. That's not true, it's UB. The compiler can do whatever it wants if it can prove that you read an uninitialized variable.

Do compilers really try to prove UB so they can use it as an excuse to silently murder kittens? That sounds so counterproductive. If it can prove UB, it should just pop an error and stop.

Re: Initialization in C++ is Seriously Bonkers

#116
post #11
post #9

Earlier quoted context omitted.

> Complex? Yes, but that's what you get with C++: Congrats on successfully summarizing the complaint. It's not mysterious, but it's gratuitously complex. And this is only variable initialization.

You ended the quote early, and my sentence went beyond the article. I said: > that's what you get with C++: very fine control of program semantics, benefit being expressive libraries. It's not gratuitous because you can't remove much of it without losing power or expressiveness (and still remain a C). Also, by complex I didn't mean complicated.

It doesn't really seem necessary for "A a = A{}" and "A a = {}" to be different things to have power and expressiveness. It really seems like uniform initialization covered just one arbitrary case while making other cases even less uniform.

Re: Initialization in C++ is Seriously Bonkers

#117
post #115

Earlier quoted context omitted.

But if you remember the underlying reason you might think that using uninitialized variables gives just gives you an arbitrary value. That's not true, it's UB. The compiler can do whatever it wants if it can prove that you read an uninitialized variable.

Do compilers really try to prove UB so they can use it as an excuse to silently murder kittens? That sounds so counterproductive. If it can prove UB, it should just pop an error and stop.

What's actually happening is a bit more subtle: The compiler is allowed to assume that the programmer in fact made no mistake and there's a reason why the UB is never actually triggered at runtime. Reasoning backwards from that can open up large optimization opportunities elsewhere, like not loading a value from memory twice, or not actually checking a condition. A good article about this that was recently discussed on HN: https://news.ycombinator.com/item?id=18575383

Re: Initialization in C++ is Seriously Bonkers

#118
post #115

Earlier quoted context omitted.

But if you remember the underlying reason you might think that using uninitialized variables gives just gives you an arbitrary value. That's not true, it's UB. The compiler can do whatever it wants if it can prove that you read an uninitialized variable.

Do compilers really try to prove UB so they can use it as an excuse to silently murder kittens? That sounds so counterproductive. If it can prove UB, it should just pop an error and stop.

> Do compilers really try to prove UB so they can use it as an excuse to silently murder kittens?

Clang in particular is quite aggressive about this, and is prone to producing surprising results. GCC has started doing this too, but it is much more conservative,

Re: Initialization in C++ is Seriously Bonkers

#119
post #76

Earlier quoted context omitted.

> The reason that stack variables are UNinitialized is (contra the article which thinks it's because the programmer didn't put an initializer in the source code) that memory is on the stack, which is allocated internal to your program and in practice was used previously by some other call for some other purpose. It is because the programmer didn't put an initializer into the source code. That's how the language is de…

In the next sentence I say: > variables must always be initialized before they’re used. Also I believe I’m quoting close to the standard there about indeterminate value. I stayed away from using the term “undefined behavior” because I’ve had a lot of problems in the past with students believing undefined behavior means “but it works if they ran a test with a particular compiler version and flags and didn’t see any pr…

> No matter how I try to equivocate undefined behavior with invalid code, it has trouble sticking.

Try telling students to add -fsanitize=undefined to their compilation flags. That might help make it clear that their code is buggy.

Re: Initialization in C++ is Seriously Bonkers

#120
post #115

Earlier quoted context omitted.

But if you remember the underlying reason you might think that using uninitialized variables gives just gives you an arbitrary value. That's not true, it's UB. The compiler can do whatever it wants if it can prove that you read an uninitialized variable.

Do compilers really try to prove UB so they can use it as an excuse to silently murder kittens? That sounds so counterproductive. If it can prove UB, it should just pop an error and stop.

What they do is not try to prove UB, but use it as a precondition for the proof that their optimizations don't change the program behavior - ie. they can assume that anything resulting in UB won't happen.
Post reply on HN