21 ms·
I have no constructor, and I must initialize
- jakewins 2y agoMan I get vertigo reading this. Reminds me of trying to understand Java constructors and object initialisation. It’s been a while now, and at least in my experience so far Go and Rusts choice of not having special constructors really simplifies a lot. Is there anyone that’s had the experience of missing constructors once you swapped away from them?
- _ZeD_ 2y agodude, java constructor are easy... that C++ stuff is really black magic and from what I understand rust constructors are basically the same as java, no?
- masklinn 2y agoRust does not have constructors at all[0], it uses factory functions (conventionally named `new_somethignsomething`) but those are not special to the language. [0] except in the more generalised haskell-ish sense that structs or enum variants can be constructed and some forms (“tuple structs” and “tuple variants”) will expose an actual function
- collinvandyck76 2y agoI've often longed for first class constructors in Go and Rust. It was more of a problem for me with Go because you can omit a struct field when building a value, something you can't do in Rust unless it has an explicit Default impl and even then you have to explicitly add ..Default::defualt() when you're building the value. I never thought that constructors were that burdensome and therefore do not understand the omission in other languages like Go and Rust that followed. Quite the opposite really -- knowing that a type always went through a predefined init was comforting to me when writing Java.
- gavindean90 2y agoI think people don’t like constructors because of the potential side effects of something happening in constructors, especially if the constructor is big or doesn’t finish properly.
- mmaniac 2y agoRust doesn't have constructors. By convention, a static method called new returns a struct - no magic.
- jakewins 2y agoI think if you think constructors in Java are easy, you are much, much smarter than I am or have missed some really, really subtle footguns. Eg: - Java constructors can return the object before they complete construction, finishing at a later time; this is visible in concurrent code as partially constructed objects - Java constructors can throw exceptions and return the partially constructed object at the same time, giving you references to broken invalid objects - Just.. all the things about how calling super constructors and instance methods interleaved with field initialization works and the bazillion ordering rules around that - Finalizers in general and finalizers on partially constructed objects specifically I don't in any way claim it's on the same level as C++, but any time I see a Java constructor doing any method calls anymore - whether to instance methods or to super constructors - I know there are dragons
- SpaghettiCthulu 2y ago> - Java constructors can return the object before they complete construction, finishing at a later time; this is visible in concurrent code as partially constructed objects > > - Java constructors can throw exceptions and return the partially constructed object at the same time, giving you references to broken invalid objects Java constructors do not actually return the object. In Java code, it would appear to the caller as though the contructor returns the new instance, but that is not really the case. Instead, the new object is allocated and then the constructor is called on the object in (almost) the same manner as an instance method. Additionally, Java constructors can only leak a partially initialized object if they store a `this` reference somewhere on the heap (for example, by spawning a thread with a reference to `this`). The assertion that this gives you a reference to a "broken invalid object" is only potentially correct from the perspective of invariants assumed by user-written code. It is perfectly valid and well-defined to the JVM. > - Just.. all the things about how calling super constructors and instance methods interleaved with field initialization works and the bazillion ordering rules around that This is a gross mischaracterization of the complexity. There is only a single rule that really matters, and that is "no references to `this` before a super constructor is called". Until very recently, there was also "no statements before a super constructor is called". > - Finalizers in general and finalizers on partially constructed objects specifically Finalizers are deprecated.
- DougBTX 2y agoInside a constructor you can access a partially initialised "this" value, and even call methods on it, which leads to rules like: "Do not call overridable methods in constructors"[0], as they can lead to surprising, non-local, bugs. Rust has functions associated with types which are conventionally used like constructors, but critically the new objects must have all their fields provided all at once, so it is impossible to observe a partially initialised object. [0] https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/quality-rules/ca2214 https://learn.microsoft.com/en-us/dotnet/fundamentals/code-a...
- titzer 2y agoVirgil solved this a little differently. The initialization expressions for fields (outside of constructors) as well as implicit assignment of constructor parameters to fields happens before super constructor calls. Such initialization expressions cannot reference "this"--"this" is only available in _constructor bodies_. Initializing fields before calling super and then the chaining of super calls guarantees the whole chain of super constructor calls will finish before entering the body of a constructor, and all fields will be initialized. Thus by construction, virtual methods invoked on "this" won't see uninitialized fields. https://github.com/titzer/virgil/blob/master/doc/tutorial/Classes.md#initialization-order https://github.com/titzer/virgil/blob/master/doc/tutorial/Cl...
- zozbot234 2y agoYou can most likely use session types to soundly observe a partially initialized MaybeUninit<MyObject> in Rust. The proper use of session types could ensure that the object is only assumed to be initialized after every field of it has been written to, and that no uninitialized fields are ever accessed in an unsound way. The issue though is that this is not automated in any way, it requires you to write custom code for each case of partial initialization you might be dealing with.
- masklinn 2y agoThere are a few somewhat esoteric cases where constructors working in-place allow magic which can be hard to replicate otherwise e.g. Rust is still missing guaranteed “placement new” type behaviour. Unless you want to `ptr::write` individual fields by hand into a `MaybeUninit`, which you can absolutely do mind but that… is not very ergonomic, and requires structs to be specifically opted into this.
- wongarsu 2y agoWhich can be an issue if you want to initialize a 2MB large heap-allocated object (e.g. heap-allocating a large nested struct or a big array). Without guaranteed “placement new” that can mean that your 2MB object gets constructed on the stack and copied to the heap. And while Linux defaults to a 4MB stack, Windows defaults to 1MB and will crash your program. Or it might work if the compiler optimizes in your favor. It's not something you encounter frequently, it can be worked around, and Rust will eventually solve it ergonomically without introducing constructor hell (probably with just a keyword). But finding the best language-level solution isn't straightforward (efforts to fix this for rust are ongoing for 9 years)
- bennettnate5 2y agoIt can also be an issue if you want to wrap any API that requires fixed memory locations for objects (such as POSIX semaphores). It's UB to call a POSIX semaphore from any other memory location than where it was initialized, so making a `Semaphore::new()` API is just asking for trouble. You can deal with it by `Box`ing the semaphore, but then you can't construct the semaphore in a shared memory segment (one of the stronger use cases for process-shared semaphores). I have a hunch this is why there's no Semaphore implementation in the Rust standard library, though it could be due to fundamental inconsistencies in semaphore APIs across OSs as well ¯\_(ツ)_/¯
- masklinn 2y agoNo, Rust doesn't have semaphores in the stdlib[0] because it was not clear what precise semantics should be supported, or what purpose they would serve since by definition they can't mitigate exclusive and thus write access to a resource and mitigating access to code isn't much of a rust convention. And nobody has really championed their addition since. Furthermore, they still present a fair amount of design challenges in the specific context of Rust: https://neosmart.net/blog/implementing-truly-safe-semaphores-in-rust/ https://neosmart.net/blog/implementing-truly-safe-semaphores... [0] technically they were there, added in 0.4, never stabilised, deprecated in 1.7, and removed in 1.8
- throwawaymaths 2y agoI mean go's zero initialization requires a bit of language lawyering sometimes too. https://codefibershq.com/blog/golang-why-nil-is-not-always-nil https://codefibershq.com/blog/golang-why-nil-is-not-always-n...
- chipdart 2y ago> It’s been a while now, and at least in my experience so far Go and Rusts choice of not having special constructors really simplifies a lot. This take makes no sense. Think about it: you're saying that not having the compiler do any work for you "really simplifies things a lot". Cool, so you have to explicitly declare and define all constructors. That's ok. But think about it, doesn't C++ already offer you that option from the very start? I mean, you are talking about a feature in C++ that is not mandatory or required, and was added just to prevent those programmers who really really wanted to avoid writing boilerplate code to lean on the compiler in and only in very specific corner cases. If for any reason you want the compiler to do that work for you, you need to be mindful of the specific conditions where you can omit your own member functions. For the rest of the world, they can simply live a normal life and just add them. How is this complicated? Complaining that special member functions make obvious things less simple is like complaining that English is not simple jus because you can find complicated words in a dictionary. Yes, you can make it complicated if that's what you want, but there is nothing forcing you to overcomplicate things, is there?
- tyg13 2y agoYou're mistaken. Rust does not require you to define all constructors. Rust does not have constructors. All structs in Rust must be initialized using brace syntax, e.g. `Foo { bar: 1, baz: "" }`. This is commonly encapsulated into static functions (e.g. `Foo::new(1, "")`) that act similarly to constructors, but which are not special in any way compared to other functions. This avoids a lot of the strangeness in C++ that arises from constructors being "special" (can't be named, don't have a return type, use initializer list syntax which is not used anywhere else). This combined with mandatory move semantics means you also don't have to worry about copy constructors or copy-assignment operators (you opt into copy semantics by deriving from Clone and explicitly calling `.clone()` to create a copy, or deriving from Copy for implicit copy-on-assign) or move constructors and move-assignment operators (all non-Copy assignments are moves by default). It's actually rather refreshing, and I find myself writing a lot of my C++ code in imitation of the Rust style.
- chipdart 2y ago
- marton78 2y agoAfter almost 20 years of experience with C++, there are still some gnarly details I wouldn't have imagined. What a God awful language! Kudos to that author for the great, eye catching title and the in depth detail!
- unwind 2y agoIn case it's not known to everyone, the title is an obvious nod to "I Have No Mouth, and I Must Scream" [1], a 1960s US sci-fi story by Harlan Ellison. 1: https://en.wikipedia.org/wiki/I_Have_No_Mouth,_and_I_Must_Scream https://en.wikipedia.org/wiki/I_Have_No_Mouth,_and_I_Must_Sc...
- bookofjoe 2y agohttps://talesofmytery.blogspot.com/2018/10/harlan-ellison-i-have-no-mouth-and-i.html https://talesofmytery.blogspot.com/2018/10/harlan-ellison-i-...
- _vaporwave_ 2y agoThat plot summary is... dark. Does anyone know how long the story is? Most of the copies I found online are collections of short stories.
- neckro23 2y agoIt's a short story, a brief one (~32 kB): https://gist.github.com/neckro/0f3a9ec60be34e3164c6677d4ecc1cb8 https://gist.github.com/neckro/0f3a9ec60be34e3164c6677d4ecc1... CW though, it is pretty grim. Very early example of the "AI takes over the world, decides humans are redundant" trope though. (Maybe the first?)
- tannhaeuser 2y agoThe question is which IHNMAIMS character the poster identifies with to have deserved his OOP misery, given all protagonists are imprisoned for life (or for eternity, actually, I believe) as a sentence for the bad things they did ;) Note there's also the adventure game created after the book, overseen and with a script also by Ellison.
- echelon 2y agoA language shouldn't be this complicated. This is dangerous and impossible for teams full of juniors and busy people with deadlines. We're only human.
- 082349872349872 2y agoI believe those teams just use constructors; this is a corner case, not SOP.
- echelon 2y agoC++ should start pulling things out of the language with new editions. It would improve quality of life dramatically.
- falcor84 2y agoHow about (C++)-- ?
- Joel_Mckay 2y agoThere was a C--, and it was an Assembly macro C like syntax based compiler. https://en.wikipedia.org/wiki/C-- https://en.wikipedia.org/wiki/C-- The GNU gcc/g++ was far more important to standardization than most people like to admit. Have a great day, =)
- pjmlp 2y agoRust style editions don't work with binary libraries, across compilers, or template code across editions, with semantic differences. That is why the epochs proposal was rejected. Additionally, the main reason many of us, even C++ passionate users, reach out to C++ instead of something else, is backwards compatibility, and existing ecosystem. When that is not required for the project at hand, we happily reach out to C#, D, Java, Go, Rust, Zig, Swift, Odin,.... instead.
- jamincan 2y ago
- wateralien 2y agoUpvote for the title.
- gattilorenz 2y agoWhat an beautiful blog theme, obviously inspired by the DEC-era computers but also clean and minimal. Refreshing!
- imperialdrive 2y agoDitto
- georgestagg 2y agoI like how the rules to the right of the headings react to the page width and how many lines are used.
- kazinator 2y ago> Otherwise, zero-initialize and then default-initialize. That can't be right ... is it? Things cannot be initialized twice. Isn't it more like "Otherwise, recurse the value-initialization over the bases and members". Then, those that are not classes or arrays get zero-initialized.
- SpaghettiCthulu 2y agoI think it would be perfectly legal to zero-initialize the entire thing and then default-initialize, because initialization assumes the value is undefined.
- bregma 2y agoYou can only initialize once. After it's been initialized you're just assigning values, and that's not what happens during initialization. It's either a misunderstanding on behalf of the author or the words as written are not conveying the correct idea.
- leni536 2y agoBoth "zero-initialize" and "default-initialize" are terms that have precise definitions. In this context if you substitute the definitions it just means first zero-initializing the non-static data members (and zeroing the padding), then calling the default constructor. It doesn't mean that the lifetime of the object starts twice, or anything weird like that.
- 3l3ktr4 2y agoThis is the best title, OP.
- gpderetta 2y ago> [...] The printed result would be 0. This is because we value-initialize t and, since T has a non-user-provided default constructor, the object is zero-initialized (hence t.x is zero-initialized) then default-initialized (calling the implicitly-defined default constructor, which does nothing). T̶h̶a̶t̶ d̶o̶e̶s̶n̶'t̶ s̶e̶e̶m̶ c̶o̶r̶r̶e̶c̶t̶:̶ a̶ d̶e̶f̶a̶u̶l̶t̶e̶d̶ c̶o̶n̶s̶t̶r̶u̶c̶t̶o̶r̶ s̶t̶i̶l̶l̶ d̶e̶f̶a̶u̶l̶t̶-̶i̶n̶i̶t̶i̶a̶l̶i̶z̶e̶s̶ t̶h̶e̶ m̶e̶m̶b̶e̶r̶s̶, n̶o̶t̶ v̶a̶l̶u̶e̶ i̶n̶i̶t̶i̶a̶l̶i̶z̶e̶. I̶ d̶o̶n̶'t̶ t̶h̶i̶n̶k̶ t̶h̶e̶r̶e̶ i̶s̶ a̶n̶y̶ d̶i̶f̶f̶e̶r̶e̶n̶c̶e̶ b̶e̶t̶w̶e̶e̶n̶ d̶e̶f̶a̶u̶l̶t̶i̶n̶g̶ i̶n̶l̶i̶n̶e̶ a̶n̶d̶ o̶u̶t̶ o̶f̶ l̶i̶n̶e̶. G̶C̶C̶ s̶e̶e̶m̶s̶ t̶o̶ a̶g̶r̶e̶e̶:̶ h̶t̶t̶p̶s̶:̶//g̶c̶c̶.g̶o̶d̶b̶o̶l̶t̶.o̶r̶g̶/z̶/r̶4̶r̶e̶5̶T̶E̶5̶a̶ edit: I missed that the author is actually value-initializing x!!! The result definitely violates expectations! Generally, the details of the rules are arcane and sometimes have non-sensical dark corners having been extended and patched up for the last 40 years. But 99.9%[1] of the time you get what you expect. I big improvement would be making default initialization explicit, and otherwise always value initialize. Explicit value initialization is so common that the very rare times I want default initialization (to avoid expensively zeroing large arrays) I need to write a fat comment. Writing "std::array<int, 100> = void;" (or whatever the syntax would be) would be much better. [1] I had an extra 9 here... I hedged.
- adrianN 2y agoOnce every thousand lines you don’t get what you expect? Rip
- chipdart 2y ago> I big improvement would be making default initialization explicit Actually initializing your instances, which is what's expected of every single instantiation, is enough to not experience any problem. This also means that if you want to call a constructor, you need to define it. This is a case of people trying to be too clever for their own sake, and complaining that that's too much cleverness for them to handle.
- hwc 2y agoI'm so glad I use Go more than C++ these days. In Go, all values are always zero-initialized if you don't explicitly assign a value. If you need a constructor, you write a regular function that returns an explicitly assigned object. I like keeping the rules of the language simple enough that there is never any confusion.
- javierhonduco 2y agoPersonally I’m not a fan of Go’s default zero-initialisation. I’ve seen many bugs caused by adding a new field, forgetting to update constructors to intialise these fields to “non-zero” values which caused bugs. I prefer Rust’s approach where one has to be explicit. That being said it’s way less complex than C++’s rules and that’s welcomef.
- ErikBjare 2y agoHaven't written Go in a long time, but I do remember being bit by this.
- maccard 2y agoI spent a year and a half writing go code, and I found that it promised simplicity but there an endless number of these kinds of issues where it boils down to "well don't make that mistake".
- gizmo686 2y agoIt turns out that a lot of the complexity of modern programming languages come from the language designers trying to make misaked harder. If you want to simplyfing by synthesising decades of accumulated knowledge into a coherent language, or to remove depreciated ideas (instead of the evolved spaghetti you get by decades of updating a language) then fine. If your approach to simplicity is to just not include the complexity, you will soon disciplinary that the complexity was there for a reason.
- zarathustreal 2y agoYea this can be problematic if you don’t have sum types, it’s hard to enforce correct typing while also having correct default / uninitialized values.
- AlexandrB 2y agoFor more C++ wackiness, I recommend the C++ FQA: https://yosefk.com/c++fqa/ https://yosefk.com/c++fqa/ It's 15 years out of date now, but also timeless since C++ rarely/never removes old features or behaviours.
- deleted 2y ago[deleted]
- bookofjoe 2y ago>I Have No Mouth, and I Must Scream (1967) https://talesofmytery.blogspot.com/2018/10/harlan-ellison-i-have-no-mouth-and-i.html https://talesofmytery.blogspot.com/2018/10/harlan-ellison-i-...
- e40 2y agoCame for this. I once talked with Harlan Ellison. He called my house when I was 17. At 2am. This was in the days of sharing a phone via a 30ft cord and taking it into your bedroom and closing the door. As teenagers would do. Martin H Greenberg and his family were staying at our house. He was calling for Martin. I was big into SciFi and had read a few of his books. The conversation was odd. I said Martin was asleep and asked who he was. Everything after hearing his name was sort of a blur. Yes, I did wake Martin and hand him the phone. It was hard to sleep after that.
- jolj 2y agoIs there a C++ tool that adds/shows all the implicit stuff that happens behind the scenes? Such as all the constructors that are being added, implicit copy constructor and all the other surprises?
- fouronnes3 2y agoBest you're gonna get is a combination of godbolt and cppinsights.
- jolj 2y agocppinsights looks like what I was looking for, there's even a vscode extension thanks
- sixtram 2y agoGreat link, I'm going to add this to my list of favorite interview questions. (^_-)
- jeffbee 2y agoI agree there is a lot of complexity in C++ in the year 2024, however I feel that much of the appearance of complexity around initialization is due to the pedantic, dogmatic use of the word "default" by the committee to mean "not".
- amluto 2y agoI’m surprised there were no snarky comments about: > So, here’s the glue between list-initialization and aggregate initialization: if list-initialization is performed on an aggregate, aggregate initialization is performed unless the list has only one argument, of type T or of type derived from T, in which case it performs direct-initialization (or copy-initialization). The word “unless” is even bold. We have fancy syntax: T t{v0}; And we also have: T t{v0, v1}; And so on. But the one-element case does not reliably work like the 2+-element case. And this is in a language that increasingly works toward making it straightforward to create a struct from a parameter pack and has support for variable length array-ish things that one can initialize like this. And the types can, of course, be templated. So you can write your own constructors, and you can initialize a tuple or array with only one element supplied, and you might trip over the wrong constructor being invoked in special cases. I remember discovering this when C++11 initializer lists were brand new and thinking it was nuts.
- TinkersW 2y agoInitializer lists is irreverent, nobody uses it anyway. Other than a few standard containers that use it, you can completely ignore the silly thing.
- alex_lav 2y agoAs is the nature of bad design, “nobody uses it other than some people sometimes” is a silly sentiment and indicative of a problem.
- Maxatar 2y agoThat's the biggest problem with them. Something isn't as dangerous when it's in your face and you need to confront it on a regular basis. What's dangerous are the things that rarely need to think about, except for that very rare moment when it bites you in the ass precisely because it's not on your mind.
- shadowgovt 2y agoI've definitely seen initializer lists recommended as best-practice in safety-critical code.
- vsgherzi 2y agothis has got to be one of my favorite blog names i've seen on this site
- pierrebai 2y agoThe article is just plain wrong about classes: if you have declared any constructor, then the language will not provide a default constructor and default-initialization will fail with a compiler diagnostic. So their claim that "T t;" will "do nothing" is incorrect. class T { public: T(int); }; T t; Will fail.
- shadowgovt 2y agoI think I missed where in the article they did a `T t;`... Doesn't seem to show up with an eyeball scan?
- vitus 2y agoIn the first few paragraphs: > Primarily, there are two kinds of initialization of concern: default-initialization and value-initialization. The rules given in the standard look roughly like this: > * For any type T, T t; performs default-initialization on t as follows: ... As GP mentions, the article's descriptions of default and value initialization are both incorrect for classes that do not have default constructors, as that code will simply not compile.
- wavemode 2y agoBut... all of the classes in the article -do- have default constructors. And all of the examples in the article do compile. So I'm confused at what point you guys are making.
- vitus 2y agoQuoting the full section on `T t;`: - If T is a class type and there is a default constructor, run it. - If T is an array type, default-initialize each element. - Otherwise, do nothing. That decision tree should read: "If T is a class type: it will invoke the default constructor. It is a compile-time error to write this if T does not have a default constructor." Not "if there is a default constructor, run it; otherwise, fall back to doing nothing." The "do nothing" applies to scalar types such as ints, and indirectly to scalar member variables that aren't explicitly initialized one way or another. Not to classes that have deleted the default constructor.
- OptionOfT 2y agoT::T() = default; > You’d expect the printed result to be 0, right? You poor thing. Alas—it will be garbage. Some things can never be perfect, it seems. Here’s a relevant excerpt from our description of value-initialization: Link: https://consteval.ca/2024/07/03/initialization/#:~:text=You%E2%80%99d%20expect%20the%20printed%20result%20to%20be%200%2C%20right%3F%20You%20poor%20thing.%20Alas%E2%80%94it%20will%20be%20garbage.%20Some%20things%20can%20never%20be%20perfect%2C%20it%20seems.%20Here%E2%80%99s%20a%20relevant%20excerpt%20from%20our%20description%20of%20value%2Dinitialization%3A https://consteval.ca/2024/07/03/initialization/#:~:text=You%... That actually isn't that weird, because it would allow any consumer of your library to change how your library behaves.
- Twisol 2y agoThe alternative not making sense doesn't automatically make this solution make sense :( It just highlights how many corners C++ has backed its design into.
- nxobject 2y agoAs an aside, I see that DEC front panel you've got there in your blog header.
- shadowgovt 2y agoRealizing the spec for C++23 is about two-and-some-change-times the length of the King James Bible has really reframed my thinking on this language. For good or for ill, I don't really trust anything that long to be something the average human can wrestle down. And when you mix in undefined behavior and the fact it's still used on safety-critical systems... It's a bit horrifying really.
- CRConrad 2y ago> Realizing the spec for C++23 is about two-and-some-change-times the length of the King James Bible has really reframed my thinking on this language. I wonder how much shorter the spec for a radically simplified version of C++ -- say, one that zero-initializes everything, and has no default constructors ("not writing a constructor raises an error" or something) -- would be? 5% 50? 95...?
- MathMonkeyMan 2y agoShow me someone who understands the rules, and I'll show you a compiler engineer... who probably doesn't understand the rules.
- gnarlouse 2y agothis title makes me want to shout "Call J. G. Wentworth, 877 Cash Now!"
- KingLancelot 2y ago[dead]
- nickysielicki 2y agoThe whole thing is wrong. Don’t put const references in your structs. Use std::reference_wrapper if you must. Edit: this response is a bit dismissive but honestly my main beef with this article is that its conclusion is just straight up wrong. Do not write your own constructors, do follow the rule of 5/3/0, and if you find yourself needing to hold a const reference, you should look out for whether you’re passing in an rval temporary… none of this is really scary.
- forrestthewoods 2y agoI’ve never used std::reference_wrapper in my life. Nor have I seen it used in any of the numerous C++ code bases I’ve worked in. Although I’m sure it’s used in deep, gnarly template BS. Your statement may be correct! But it’s certainly not common knowledge in my experience.
- shrimp_emoji 2y agoI use them now and then -- and I never touch templates. It's just a reference you can reassign. Or, in other words, truly a pointer that can't be null. :D (And that you can actually use in collections that require reassignable types.)
- nickysielicki 2y agoMy stance is just based on cpp core guidelines: https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#Rc-constref https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines... https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#Rc-zero https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines... std::reference_wrapper still can’t save you from yourself, but it’s better than violating the first link and ending up in this limbo that OP is talking about. See also: https://youtu.be/YxSg_Gzm-VQ https://youtu.be/YxSg_Gzm-VQ (about 3:30 in)
- lenkite 2y agoThat link says nothing about std::reference_wrapper ?
- IAmLiterallyAB 2y agoHorrific. One of the things that scares me about C++. A real shame because it has some cool features and some brilliant minds working on it. I'm hoping something like Herb's C++ syntax 2 will make the language useable for mortals like me.
- chipdart 2y ago> Horrific. I think you're whining about something that doesn't pose any problem to anyone with any passing experience in software development. The examples in the blog post boil down to far-fetched cases devised to trigger corner-cases of a feature where a programming language in exceptional cases auto-generates specific functions when programmers somehow explicitly decided not to do it themselves. The blogger then proceeds to explore edge conditions that lead these exceptional cases to either be enabled or disabled. In the meantime, be mindful of the fact that this is about a language with a clear design goal of paying only for what you use,and also the widely established rule of 3/rule of 5, which is C++101 and states that when anyone defines one of these special member functions, they should define them all. Why? Because it's C++101 that these special member functions are only generated by the compiler in specific corner cases, and given their exceptional nature the compiler will not generate them automatically if any of the requirements is not met. Therefore, any programmer who goes through the faintest introduction knows that they have to set the constructors they will use. Is this outlandish? Also, does it catches anyone by surprise that you need to initialize instances when you instantiate them? Is this too much of a gotcha to justify being called "horrific"? I think people like you just feel the need to have something to complain about. In the meantime, everyone in the real world happily does real work with them without any fuss.
- quietbritishjim 2y agoAre you joking? The profusion of initialisation types and exceptions to those rules (and exceptions to those exceptions...) absolutely pose a practical problem to all C++ programmers everywhere.
- IAmLiterallyAB 2y ago> I think people like you just feel the need to have something to complain about Thanks for the ad hominem