This bug had nothing to do with c++ and its ergonomics, let alone it's safety.
> Unfortunately when populating the denomination member variable, an equality operator was used instead of assignment, resulting in the denomination always being zero, as set in the class constructor.
That is absolutely a bug in C++'s ergonomics. Languages that use pascal-style := for assignment would not have this problem. Languages that don't have the surprising value behaviour of = would not have this problem. Hell, even as crude a language as Java would not have this problem because it doesn't allow an integer to implicitly decay to a boolean.
Building with warnings on would also have caught it, but the fact that someone started a new project without this warning turned on shows that C++'s defaults around warnings are bad, which is an ecosystem ergonomics issue.
I was using C++ in 1994. I am fully amused today to hear 'ergonomics' attributed to the language, even with the qualifier 'bad.' I'll spare you the rest of this "back in my day" post. I just can't fault the language for a project creator not including -Wall in the Makefile or whatever they used to build.
Indeed, just as in every other ML-family language since 1973. (I'm glad these things are finally getting mainstream attention, but I'm not sure why people get so excited about "Rust features" that are almost all taken straight from Ocaml)
Hey, I'm just glad to see 1970's PL research finally making it to the mainstream(ish), regardless of which language gets the marketing credit for it.
I think the main advantage Rust has over OCaml is that it is syntactically more like C. But, hey, if it's what gets HM-style type inference to the masses, I'll take it.
This doesn't have anything to do with the value behaviour of =. The statement in question was intended to be a simple assignment, throwing away the value of the = operator and only using its side-effect. Instead an equality operator was used, which produced no side-effect.
So if you want to blame anything, blame the concept of expression statements, I guess?
The idea that you form a value by creating an uninitialized one and then filling in its fields is dumb. (I suspect the field value wasn't even 0 as such but rather undefined, and the implementation happened to make it 0?). Better languages have you initialize the value directly and you can't access it until it's fully initialized. C/C++ are just really bad at expressing nontrivial values, even value literals.
(Discarding a value ought to be an error too, though that's more cumbersome to work with)
You can rightfully blame having state setting be part of your language. It is easier to program without state than with it, just like it's easier to juggle 2 balls than 3. Without state (or with the absolutely minimum of it) you can not make mistakes with it. Also, if your state-setting operator is super similar to your equality-checking operator, you can fall into this trap (like the devs in question did).
Programming without state is something that has helped me personally make my code much better. I produce less bugs by far since I stopped relying on state for so many things. A lot of micro-optimisations are not doable for me. In exchange I guess I get to run things in parallell very easily. But mostly, I get fewer bugs, which makes my life and the lives of my customers better.
Amen to that! If Rich Hickey is reading this - it is to you I owe my thanks for the many hours I have not spent on fixing state bugs. Clojure was my first functional love story.
So, just as in c++ there is a different operator of assignment and equality that requirs you to type a different thing. User error and testing failure.
Yes it is. Assignment is another word for writing state. If your programming environment doesn't include a way to set state, you will never do it. Why is doing the dangerous task of writing state so easy you just have to hit one key to do it in C++?
Let's collectively put our seat belts on, colleagues!
Even in Haskell, writing state is as easy as += or <- and this is used in nearly every actual program.
A cryptocurrency implementation like this doesn't need a language that makes state impossible. It needs static analysis, model checking, and proofs. This would be true even if it were written in your favorite functional language.
Sorry for being unclear. In my timezone it's pretty late.
If there was not state, the coder wouldn't had tried to set it. I don't think a language needs to have the `=` operator easy and close at hand. Had that not been the case, this bug (and oh so many others) would never had existed.
> Unfortunately when populating the denomination member variable, an equality operator was used instead of assignment, resulting in the denomination always being zero, as set in the class constructor.
So = Vs ==