7 ms·
This idea that everything must be initialized (i.e. no undefined or non-deterministic behavior) should never be forced upon a language like C++ which rightly as
by waynecochran 1y ago
This idea that everything must be initialized (i.e. no undefined or non-deterministic behavior) should never be forced upon a language like C++ which rightly assumes the programmer should have the final say. I don't want training wheels put on C++ -- I want C++ do exactly and only what the programmer specifies and no more. If the programmer wants to have uninitialized memory -- that is her business.
- anon-3988 1y agoIf they want the program to do exactly what is told they won't get to have optimization.
- waynecochran 1y agoThat's the whole point of UB -- it leaves open more possibilities for optimization. If everything is nailed down, then the options are more restricted.
- dminik 1y agoIt doesn't really seem worth it. https://web.ist.utl.pt/nuno.lopes/pubs/ub-pldi25.pdf https://web.ist.utl.pt/nuno.lopes/pubs/ub-pldi25.pdf > The results show that, in the cases we evaluated, the performance gains from exploiting UB are minimal. Furthermore, in the cases where performance regresses, it can often be recovered by either small to moderate changes to the compiler or by using link-time optimizations.
- GrantMoyer 1y agoThe problem is that the initialization semantics are so complex in C++ that almost no programmer is actually empowered to exercise their final say, and no programmer without significant effort. And that's not just said out of unfamiliarity. I'm a professional C++ developer, and I often find I'm more familiar with C++'s more arcane semantics than many of my professional C++ developer co-workers.
- vjvjvjvjghv 1y agoThe dev should have the option to turn it off but I think that removing a lot of undefined and non deterministic behavior would be a good thing. When I did C++ I initialized everything and when there was a bug it could usually be reproduced. There are a few cases where it makes sense performance wise to not initialize but those cases are very small compared to most other code where undefined behavior causes a ton of intermittent bugs.
- yxhuvud 1y agoThe discussion about what should be the default behavior and of what should be the opt-in behavior is very different from what should be possible. It is definitely clear that in c++, it must be possible to not initialize variables. Would it really be that unreasonable to have initialisation be opt-out instead of opt-in? You'd still have just as much control, but it would be harder to shoot yourself in the foot by mistake. Instead it would be slightly more easy to get programs that can be optimised.
- frollogaston 1y agoC++ is supposed to be an extension of C, so I wouldn't expect things to be initialized by default, even though personally I'm using C++ for things where it'd be nice. I'm more annoyed that C++ has some way to default-zero-init but it's so confusing that you can accidentally do it wrong. There should be only one very clear way to do this, like you have to put "= 0" if you want an int member to init to 0. If you're still concerned about safety, enable warnings for uninitialized members.
- gpderetta 1y agomy_type my_var = {}; almost always does the right thing. The almost is unfortunate.
- dwattttt 1y agoC++ is supposed to be an extension of <thing with bad default>, so I wouldn't expect <a good default>. Things can change & grow, that's why we make new standards in the first place.
- frollogaston 1y agoIt'd be confusing for C++ to differ from C in how primitives work. If they want to evolve C too then sure.
- frollogaston 1y ago
- tonyhart7 1y ago"If the programmer wants to have uninitialized memory -- that is her business." idk, seems like years of academic effort and research wasted if we do the way C++ do it
- loeg 1y agoAs someone who has to work in C++ day in and day out: please, give me the fucking training wheels. I don't want UB if I declare an object `A a;` instead of `A a{};`. At least make it a compiler error I can enable!
- ryandrake 1y agoIdeally, there would be a keyword for it. So ‘A a;’ would not compile. You’d need to do ‘A a{};’ or something like ‘noinit A a;’ to tell the compiler you’re sure you know what you are doing!
- waynecochran 1y agoNot me. I want to give the optimizer the freedom to do its thing. If I say something does not need to be initialized, then the optimizer has one less constraint to worry about.
- wiseowise 1y agoWe’ve already understood you don’t want sane language design, you don’t need to repeat it ten times.
- bregma 1y agoCan you identify a compiler released in the last, say, 20 years that does not give a warning (or error, if the compiler is instructed to turn warnings into errors) for uninitialized variables when warnings are enabled?
- loeg 1y agoDoes Clang 20 (March 2025) meet your criteria? https://godbolt.org/z/W9Tzhfn4s https://godbolt.org/z/W9Tzhfn4s
- int_19h 1y agoMost of them. They have to, because declaring an uninitialized variable that is later initialized by passing a reference or pointer to it to some initialization function is a rather common pattern in low-level C++. In a sane language that would be distinguishable by having the direction explicit (i.e. things like in/out/ref in C#), and then compiler could complain for in/ref but not for out. But this is C++, so...
- charlotte-fyi 1y agoThe entire problem is that what the programmer wants to do and what the program actually does isn't always clear to the programmer.
- kstrauser 1y agoBy that logic, you'd have to dislike the situations where C++ does already initialize variables to defined values, like `int i;`, because they're removing your control and forcing training wheels upon you. So, do you?
- deleted 1y ago[deleted]
- jcelerier 1y agoint i; does not initialize the value.
- kstrauser 1y agoIt's a gotcha to be sure. Sometimes it does, sometimes it doesn't. From a reference[0]: #include <string> struct T1 { int mem; }; struct T2 { int mem; T2() {} // “mem” is not in the initializer list }; int n; // static non-class, a two-phase initialization is done: // 1) zero-initialization initializes n to zero // 2) default-initialization does nothing, leaving n being zero int main() { [[maybe_unused]] int n; // non-class, the value is indeterminate std::string s; // class, calls default constructor, the value is "" std::string a[2]; // array, default-initializes the elements, the value is {"", ""} // int& r; // Error: a reference // const int n; // Error: a const non-class // const T1 t1; // Error: const class with implicit default constructor [[maybe_unused]] T1 t1; // class, calls implicit default constructor const T2 t2; // const class, calls the user-provided default constructor // t2.mem is default-initialized } That `int n;` on the 11th line is initialized to 0 per standard. `int n;` on line 18, inside a function, is not. And `struct T1 { int mem; };` on line 3 will have `mem` initialized to 0 if `T1` is instantiated like `T1 t1{};`, but not if it's instantiated like `T1 t1;`. There's no way to tell from looking at `struct T1{...}` how the members will be initialized without knowing how they'll be called. C++ is fun! [0]https://en.cppreference.com/w/cpp/language/default_initialization https://en.cppreference.com/w/cpp/language/default_initializ...
- Maxatar 1y agoIt's so ironic hearing a comment like this. If what you really want is for C++ to do only what you strictly specified, then you'd always release your software with all optimizations disabled. But I'm going to go out on a limb here and guess you don't do that. You actually do allow the C++ compiler to make assumptions that are not explicitly in your code, like reorder instructions, hoist invariants, eliminate redundant loads and stores, vectorize loops, inline functions, etc... All of these things I listed are based on the compiler not doing strictly what you specified but rather reinterpreting the source code in service of speed... but when it comes to the compiler reinterpreting the source code in service of safety.... oh no... that's not allowed, those are training wheels that real programmers don't want... Here's the deal... if you want uninitialized variables, then explicitly have a way to declare a variable to be uninitialized, like: int x = void; This way for the very very rare cases where it makes a performance difference, you can explicitly specify that you want this behavior... and for the overwhelming majority of cases where it makes no performance impact, we get the safe and well specified behavior.
- frollogaston 1y agoHow about int x = 0 if you want 0. Just `int x;` doesn't make it clear that you want 0.
- kstrauser 1y agoSafe defaults matter. If you're using x to index into a array, and it's randomly initialized as +-2,000,000,000 because that's what happened to be in that RAM location when the program launched, and you use it before explicitly setting it, you're gonna have a bad time. And if you used it with a default value of 0, you're going to end up operating on the 0th item in the array. That's probably a bug and it may even be a crasher if the array has length 0 and you end up corrupting something important, but the odds of it being disastrous are much lower.
- conorjh 1y ago[dead]
- 90s_dev 1y agoThat's the inherent tension, though, isn't it? A programmer wants the compiler to accept code that looks like a stupid mistake when he knows it's not. But he also wants to have the compiler make sure he isn't making stupid mistakes by accident. How can it do both? They're at odds.
- wiseowise 1y ago> How can it do both? They're at odds. By doing what’s right. https://en.wikipedia.org/wiki/Principle_of_least_astonishment https://en.wikipedia.org/wiki/Principle_of_least_astonishmen...
- titzer 1y ago> I want C++ do exactly and only what the programmer specifies and no more. Most programmers aren't that good and you're mostly running other people's code. Bad defaults that lead to exploitable security bugs is...bad defaults. If you want something to be uninitialized because you know it then you should be forced to scream it at the compiler.
- conorjh 1y ago[dead]
- marsten 1y agoUnfortunately C++ ended up with a set of defaults (i.e., the most ergonomic ways of doing things) that are almost always the least safe. During most of C++'s development, performance was king and so safety became opt-in. Many of these can't be blamed on C holdover. For example Vector.at(i) versus Vector[i] – most people default to the latter and don't think twice about the safety implications. The irony is that most of the time when people use std::vector, performance is irrelevant and they'd be much better off with a safe default. Alas, we made our bed and now we have to lie in it.
- int_19h 1y agovector::at() is an interesting example. Most of the time, you don't use it because you don't index vectors in the first place - you use iterators, and there's no equivalent of at() for them that is guaranteed to throw when out of bounds.
- flavio81 1y ago>I want C++ do exactly and only what the programmer specifies Good luck with that.