Ownership and lifetimes
Ownership and lifetimes
Posted Jul 12, 2021 10:02 UTC (Mon) by tialaramex (subscriber, #21167)In reply to: Ownership and lifetimes by ncm
Parent article: Announcing Arti, a pure-Rust Tor implementation (Tor blog)
Stroustrup's long tedious book has no section about ownership. Its awful - presumably machine-generated - index lacks entries for ownership, owning, or related words. Stroustrup's periodic rants about style or philosophy of programming did not seem to (in the time I had to re-read them for this comment) mention the idea. It was, I will thus claim, "Not top of mind". Multiple inheritance was important to Stroustrup. Overloading the pointer reference operator was important. Ownership? Never warrants a mention.
Years later the eventual standard C++ has a smart pointer, auto_ptr. But, auto_ptr doesn't reflect the idea of ownership. If anything it muddies the water, a program with auto_ptrs is confusing, or worse, confused, about what is owned and who by.
So in 2011 (ten years ago) C++ gets unique_ptr, shared_ptr, weak_ptr and so on. These, at last, reflect ownership. The unique_ptr owns the thing to which it is a unique pointer, a weak_ptr explicitly doesn't own anything. But C++ 11 still also has and uses raw pointers, and by this point C++ programmers are also using a lot of references, some of them believe references imply ownership, others the exact opposite. Worse, programs are entitled in C++ to just extract the raw pointer from all these smart pointers except weak_ptr (where for obvious reasons there might sometimes not be a raw pointer) and they do.
Only when you look at work proposed for future C++ do you see the sort of enlightenment about Ownership that Rust has.
And that's only half the story. I titled my comment "Ownership and lifetimes". While C++ grew some ideas about Ownership ten years ago, it still doesn't have Lifetimes. Bjarne has proposals, with straw man implementations for the basic idea, but I'd be astonished if (modulo ongoing concerns that Rust is eating their lunch) his feature makes it into C++ 23 because C++ is today a very Conservative programming language, much more ready to find reasons to do nothing than to change and grow.
Finally, you are concerned that Rust compilation is too slow. One of the reasons C++ in particular is able to be fast is a reckless, almost outright negligent approach to basic engineering. The One Definition Rule. To enable the compiler to process as many translation units as it likes, simultaneously and without communicating, C++ has a rule which says that a C++ program must only have One Definition for symbols visible from multiple translation units. This doesn't feel so bad right? Surely you will get an error from the compiler if you violate this rule? Nope. The compiler can't be sure it will ever notice, and if it doesn't the resulting binary is nonsense. That's why the ODR exists. As a result, C++ has "False positives for the question: Is This A Program?". This is clearly awful software engineering. But it _is_ faster for whatever that was worth.
Posted Jul 12, 2021 15:30 UTC (Mon)
by khim (subscriber, #9252)
[Link] (13 responses)
I think ownership is similar to zero and negative numbers. Romans have built very powerful and engineering-savvy (by ancient standards) civilization. Without knowing zero. It took centuries for it to travel from India to the West. Negative numbers took even longer. Yet today these are something we learn in school or even preschool. Similar, but more recent, example: two's complement numbers. They were used by EDSAC ¾ century ago. Today they are “no brainer”, everyone uses them. Yet when in 1989 C standard was written they were not established enough for the C standard to define signed overflow result! It was declared an “undefined behavior” and it was opinions about them started that long feud between C compiler developers and C developers… In the other post ncm talks about backward compatibility as the reason why Rust feels much safer than C or C++. But what kind of backward compatibility can be affected if you just say “it's no longer an undefined behavior to add MAX_INT and 1”? On the contrary: the whole reason switch from C/C++ to Rust is contemplated (although not guaranteed, obviously) is because C/C++ compilers treated it's users as “captive audience” for so long: while they retained “theoretical backward-compatibility” (as in: nonexistent code which never triggers obscure “undefined behaviors” which hardware and OS define precisely — should work after compiler update) they broke “practical backward-compatibility” (as in: code which was tested and ironed-out by decades of development was suddenly declared “non-compliant” and was broken). Rust was never intended as actual C++ replacement (although today a lot of people are actually contemplating if that may be possible or not) but it follows Linus rules to the backward compatibility: The rule is not "we don't break non-buggy user space" or "we don't break reasonable user-space". The rule is simply "we don't break user-space". Even if the breakage is totally incidental, that doesn't help the _user_. It's still breakage. With addon breaking user space is a bit like trees falling in the forest. If there's nobody around to see it, did it really break? Yes, before they can adopt such a stance they needed to spend almost a decade ironing out problems in the basics of Rust and making sure actual programs which are built against stable Rust features wouldn't contain too many crazy things. C and C++ always allowed crazy programs thus declaring exactly this principle is, probably, not possible. But complete and utter disregard to expectations and use of C and C++ by real programmers definitely triggered the crisis. Ultimately, after enough breakages, which were dismissed with “hey, standard allows us to do what we do, go fix your 20-years old code” it painted C/C++ compiler developers not as C/C++ developer friends, but as adversaries. The end result: after long, hard, really arduous process C/C++ compiler developers have finally brought C and C++ to the point where collection of artificial puzzles the language imposes on top of each programming task (all these “don't ever rely on two's complement arithmetic even if it's guaranteed by standard”, “never do arithmetic on Also: when you are doing “bad things” in C/C++ your punishment is often much harsher: instead of getting clear and simple compiler errors you observe how your program turns into pile of goo. But it's 100% truth: if Rust would ever replace C/C++ then it would be shared effort where achievements of C/C++ compiler developers at making C/C++ insanely, unaffordably, dangerous would be regarded as critical step.
Posted Jul 12, 2021 17:51 UTC (Mon)
by ncm (guest, #165)
[Link] (1 responses)
It is clever to add links to other postings, and wholly invent remarks to pretend to quote from them. It is even more clever to invent things that must surely have happened before he was born. But it is not clear why anyone should try to tease out the few, lonely correct statements that accidentally appear in the roiling cloud of phantasms presented.
Posted Jul 12, 2021 18:05 UTC (Mon)
by corbet (editor, #1)
[Link]
Thank you.
Posted Jul 12, 2021 18:52 UTC (Mon)
by JanC_ (guest, #34940)
[Link] (9 responses)
Posted Jul 13, 2021 10:34 UTC (Tue)
by khim (subscriber, #9252)
[Link] (8 responses)
This was logical back 1989. Today only two's complement representation is supported and all relevant CPUs handle overflow just fine. And if compiler developers worry about benchmarks then they can always use an appropriate switch to restore obsolete behavior. The problem with C/C++ is not certain peculiarities with misunderstandings about some complex corner-cases (it's inevitable when complex systems are involved) but absolute conviction of compiler developers in the fact that “mere users” don't even deserve a discussion. “It's my way or the highway” attitude permeates the discussion. Well… Rust looks like a nice place on the highway, so maybe it's time to pick 2nd option.
Posted Jul 13, 2021 20:51 UTC (Tue)
by mrugiero (guest, #153040)
[Link] (7 responses)
Posted Jul 14, 2021 9:24 UTC (Wed)
by khim (subscriber, #9252)
[Link] (6 responses)
If I understand correctly they wanted to support systems where signed overflow causes a trap without introducing a ways to intercept that trap. But declaring it “undefined behavior” they achieved that goal: system which don't cause overflow have no need to intercept that trap while systems which cause it are not valid C. Not sure how much sense that did even back in 1989, but in 2020 it doesn't make any sense at all: there are few CPUs which may still generate signals on overflow, but I don't know any where that's not optional. And now, when two's complement is mandatory, workaround is, actually, “very simple”. Instead of And yes, of course you stuff that into a simple templated function. Except since there are no standard modules, no central repo and so on… everyone who wants/needs it would probably need to implement it separately. Which would, most likely, lead to bugs like an uncaught attempts to use that function to check overflow of And these guys are talking about artificial puzzles the language imposes on top of each programming task? Really?
Posted Jul 15, 2021 2:16 UTC (Thu)
by mrugiero (guest, #153040)
[Link] (5 responses)
But yeah, talking about artificial puzzles when you have all those kinds of behavior and you don't even mandate warnings when you hit them is a bit hypocritical.
Posted Jul 15, 2021 14:12 UTC (Thu)
by mathstuf (subscriber, #69389)
[Link] (3 responses)
I may be misremembering, but didn't some platforms not provide a way to tell? That would require the compiler to emit manual checks for every possible overflowing operation in order to guarantee *a* behavior. This would also mean that optimizing to, e.g., FMA instructions is basically impossible because if the intermediate ops overflow, that needs to be handled as well.
But if there are no platforms that lack an "overflow happened" flag…meh.
Posted Jul 15, 2021 15:56 UTC (Thu)
by matthias (subscriber, #94967)
[Link]
If you do not know which platform your code will run on, you can still be not sure what the result of x+100 is in case of overflow, but you can at least be sure what (x+100)&0 is. And you can be sure that if you do an assertion x+100>x to test for an overflow that the assertion is not optimized away. Ok, it can be optimized away of the compiler can prove that there is not overflow, but this is no problem.
Posted Jul 15, 2021 16:26 UTC (Thu)
by farnz (subscriber, #17727)
[Link] (1 responses)
If such platforms exist and need to be cared about (like you, I'm not sure if they did, or did not), an easy solution would be to make the behaviour of signed integer overflow unspecified, rather than undefined.
In the C language spec, there are four groups of behaviour (from strongest definition to weakest):
If signed integer overflow became unspecified, such that the result of a signed integer overflow could be any integer value, then we're in a much better place. The compiler can just use the machine instruction (assuming it doesn't trap), and we don't have the pain where the compiler goes "well, if this is signed overflow, then behaviour is undefined, ergo I can assume it's not, ergo I can optimise out a check"; instead, signed overflow has to produce an integer, but which integer is not known by the code author.
Posted Jul 15, 2021 16:42 UTC (Thu)
by khim (subscriber, #9252)
[Link]
This is all well and good, but this requires some form of consensus. And in C/C++ world discussions are just not happening. Why have the coveted “pointer provenance” proposals were not incorporated into standard in 15 years (and counting)? Because not even C/C++ compiler writers can agree with each other. -std=friendly-c proposal had the exact some fate. And when someone tries to resolve the issue by “starting from scratch”… the end result is D, Java, C# or Rust… never a “friendly C”… Rust is just the first such “new C” language which is low-level enough to actually be usable for all kinds of usages. Starting from lowest-level just above assembler.
Posted Jul 20, 2021 10:25 UTC (Tue)
by anton (subscriber, #25547)
[Link]
Posted Jul 20, 2021 9:58 UTC (Tue)
by anton (subscriber, #25547)
[Link]
Posted Jul 13, 2021 16:15 UTC (Tue)
by plugwash (subscriber, #29694)
[Link] (9 responses)
To actually use the object owned by a C++ smart pointer, you are pretty much forced to explicitly (e.g. "get") or implicitly (e.g. operator* or operator->) extract a raw pointer or reference.
Which ties into your point about lifetimes, once that raw pointer or reference is extracted (again either explicitly or implicitly) there is nothing to ensure that the smart pointer outlives the raw pointer or reference that was extracted from it.
Posted Jul 13, 2021 20:56 UTC (Tue)
by mrugiero (guest, #153040)
[Link] (8 responses)
Posted Jul 13, 2021 23:16 UTC (Tue)
by roc (subscriber, #30627)
[Link] (7 responses)
Posted Jul 13, 2021 23:18 UTC (Tue)
by roc (subscriber, #30627)
[Link] (5 responses)
Posted Jul 14, 2021 9:32 UTC (Wed)
by khim (subscriber, #9252)
[Link] (4 responses)
Posted Jul 14, 2021 12:06 UTC (Wed)
by mathstuf (subscriber, #69389)
[Link] (3 responses)
- destroy
Rust can end `p`'s lifetime at the `foo` call, but C++ has lifetimes go to the end of the scope no matter what because there's no mechanism to say "`p` no longer exists and is now `foo`'s problem".
Posted Jul 14, 2021 12:44 UTC (Wed)
by khim (subscriber, #9252)
[Link] (2 responses)
True, sorry I wasn't clear. Object owned by It's actually even worse than that: Clang have attribute which solves that issue, but libstdc++ doesn't use it (and I'm not even sure if libc++ actually uses that attribute already). That's why I know some companies which demand that As I have said: “modern C++” is just a huge collection of footguns of different sizes and shapes thus it sounds really funny when it's proponent start talking about artificial puzzles the language imposes on top of each programming task. At least these rules exist in some kind of central location and compiler actually verifies them! Much better than when their violation turns your program into pile of goo without any complains from the compiler.
Posted Jul 14, 2021 13:04 UTC (Wed)
by mathstuf (subscriber, #69389)
[Link] (1 responses)
I tend to just use "Plain text" here because HTML is a pain to write by hand and seem to wish that Markdown of some kind worked :) . That said, I cannot guarantee that it isn't a footgun you weren't aware of ;) .
> std::unique_ptr can not be passed in register.
True. There's discussion about breaking the ABI for this (and other things), but ABI breaking is a *huge* topic and you have the monorepo-using "we rebuild everything ourselves so what even is ABI stability" on one side and the "we have critical libraries we cannot recompile anymore because we lost the source 10 years ago" on the other. I have no idea if that discussion will go anywhere other than heat generation, but I hope something *useful* comes out of it at least even if it is just "let's design in some escape hatches for ourselves in the future".
Posted Jul 17, 2021 16:06 UTC (Sat)
by mrugiero (guest, #153040)
[Link]
Posted Jul 15, 2021 2:10 UTC (Thu)
by mrugiero (guest, #153040)
[Link]
Posted Jul 14, 2021 7:28 UTC (Wed)
by ncm (guest, #165)
[Link] (14 responses)
Stroustrup never, ever rants. When he writes, every word counts. To perceive ranting only demonstrates confusion.
Your confusion about the One Definition Rule is revealing. In fact, the only requirement to spend an entire career coding C++ never once troubled by violations of the ODR is simply to obtain declarations via headers, rather than copy-pasting them. C has always been subject to undetected failures resulting from identical malpractice; what is new is that C++ gives the rule a formal name. C's linkage model, inherited by C++ for backward compatibility, brought with it C's weaknesses, but C++ now provides module support..
To believe that object ownership and lifetimes have not always been understood and actively managed as a matter of course by all C++ (and C) coders demonstrates further confusion.
To believe that C++ is not rapidly growing and changing is to believe a fantasy that C++20 is hardly different from C++17, from C++14, from C++11, from C++03, from C++98. In fact no language defined by a Standard has evolved more over that time, and few of the rest have. As more people adopt C++ anew in any given week than have ever heard of Rust, there is no worry about lunch. "There are only two kinds of languages: the ones people complain about, and the ones nobody uses." When we see more complaints about Rust than marveling over its ability to do what has been done before, it will merit more attention.
Writing fantastic falsehoods about a language and its users reveals nothing about them, but much about the writer.
Posted Jul 14, 2021 8:25 UTC (Wed)
by Cyberax (✭ supporter ✭, #52523)
[Link] (1 responses)
That's incorrect. You can get ODR violations by having multiple clashing template specializations, that can be in different parts of the application (for the added fun).
Back in MSVS 2006 days, I also spent several days debugging an issue where two inline functions (exempt from ODR) had different padding due to different compilation options.
Posted Jul 14, 2021 9:40 UTC (Wed)
by khim (subscriber, #9252)
[Link]
No need for even that. Compile your header once with Have fun. This story just never dies.
Posted Jul 14, 2021 8:33 UTC (Wed)
by Cyberax (✭ supporter ✭, #52523)
[Link] (3 responses)
Honestly, C++ is not growing rapidly. C++20 improvements were mostly in libraries and infrastructure around them.
The major language-level feature in C++20 are concepts, but they had to be cut down quite a bit. Coroutine support is at the barest minimum possible. Modules haven't made it either.
Posted Jul 15, 2021 5:52 UTC (Thu)
by ncm (guest, #165)
[Link] (2 responses)
Posted Jul 15, 2021 13:43 UTC (Thu)
by mathstuf (subscriber, #69389)
[Link]
Posted Jul 18, 2021 13:13 UTC (Sun)
by flussence (guest, #85566)
[Link]
Posted Jul 14, 2021 9:28 UTC (Wed)
by jezuch (subscriber, #52988)
[Link] (1 responses)
Newer compilers actually warn about ODR violations. Previously is was completely silent, so nobody knew how much they were violating it. I once compiled some random C++ program with such a compiler and I just sat and watched as the ODR violation warnings just scrolled by, on and on, endlessly.
So. "The difference between practice and theory is bigger in practice than in theory." (I think it's an old engineering saying.)
Posted Jul 14, 2021 12:26 UTC (Wed)
by tialaramex (subscriber, #21167)
[Link]
Posted Jul 14, 2021 15:20 UTC (Wed)
by tialaramex (subscriber, #21167)
[Link]
So, the Fact is that Stroustrup doesn't talk about ownership in that book. The much later (less than ten years old as I write this) Fourth Edition does talk extensively about ownership. Can't shut up about it actually. In some places, nearby text survives, or has been transplanted from earlier editions, but the talk of ownership is new. Why? Because of shared_ptr and unique_ptr which did not exist when the Second Edition was written. This inspires Stroustrup to explain even before introducing any C++ syntax at all, that programmers must "represent ... Ownership relationships" in their code. Which, in C++ 11 they now can try to do.
Throughout the Fourth Edition's "Tour" of C++, there are opportunities, taken or at least pointed out to the reader for their own benefit, to express Ownership. The Desk Calculator example explicitly tracks whether it owns the Input Stream it is using, offering methods to give it a reference (which it doesn't own) or a raw pointer (which it does) and clean up appropriately. Second Edition makes no mention of this, it too has a Desk Calculator example, but it doesn't bother with Input Streams, it just reaches inside the system's standard input and mangles that directly.
So, you're wrong, factually even if you firmly believe now that ownership has "always been understood and actively managed" it seems to have escaped mention by the language's father in their text intended to introduce the language _until_ decades later the language grew facilities to actually try to "actively manage" this problem.
Lifetimes are an interesting contrast. The Second Edition does spend a few paragraphs on this topic, but mostly the reader is encouraged not to think about it too hard. Objects begin living when they're Constructed, and this lifetime ends when their name goes out of scope whereupon they will be Destroyed. Except, that's not quite true and there are a few paragraphs trying to justify that before a reference to paragraphs later in the book about the Free Store.
By the Fourth Edition, lifetimes get their own sizeable Chapter in the much larger book, "Construction, Cleanup, Copy and Move". So I agree that by this point Stroustrup is aware that this is a problem, indeed that chapter uses words like "trap" and "mistake" and most sub-sections are accompanied by considerable verbiage basically encouraging the programmer to try harder not to get this wrong. But he doesn't have anything to really propose as a solution. Yet.
Today, Stroustrup has a proposed change to C++ to add actual lifetime tracking. I don't expect it will make it into C++ 23. You claim that Stroustrup "never, ever rants" but he seems quite animated when it comes to the committee not accepting all his ideas as quickly as he might like or adjusting them in ways he isn't pleased with, and equally animated about cutting down other people's proposals.
Posted Jul 14, 2021 15:37 UTC (Wed)
by mathstuf (subscriber, #69389)
[Link] (2 responses)
Just had to deal with this last week in fact. ODR violations are rampant when some dependency does not follow C++ "best practices" nor uses extra-language bits that are compiler/platform dependent (`__attribute__(visibility)` and `__declspec`).
One of our dependencies doesn't export symbols properly. Luckily, CMake has a way to say "le sigh, just export everything" on Windows to fix that problem. However, there's a deeper problem lurking in such a codebase: RTTI duplication. There are these simple interface classes that have their definitions completely in the header. Seems reasonable; header-only is fine, right? However, the source code of the library does `typeid` comparisons with a `std::type_info` that is passed in to see which of these interface types you're asking about. Because the complete definition (trivial `{}` bodies for the ctor and dtor with pure virtual methods otherwise) are in the header, every library that sees this declaration can say "huh, no export symbol? I can make it mine" and generate its own unique RTTI table for the type. The linker will resolve these together into a shared library boundary, but nothing resolves it across a shared library boundary at runtime, so you then get two different `typeid` blocks for the same type. Hilarity ensues when the dependency goes "yeah, I have no idea what you're on about, have a `nullptr`".
Now, C++ *could* have just standardized `export` or some other syntax to say whether a declaration "belongs" to the current TU's target or not, but that requires macros at compile time to know which library you're actually compiling for so things get linked up properly. And C++ *hates* talking about compilation strategies beyond "pile of TU outputs linked into a program" because it never bothered to reign in the madness from the beginning and now suggesting anything is likely to get somebody clutching pearls immediately. So, C++20 has modules where what is "in" and what is "out" can be more easily tracked with actual standard-compliant syntax, but this has been an issue since C's textual inclusion compilation model was a thing and only now we have a solution that requires rewriting all of your headers and leaving old, dumb `%.o: %.cpp` build systems behind anyways (because compiling C++20 modules is the same problem as compiling Fortran modules and everyone remembers how much fun that has been, right?).
Posted Jul 15, 2021 11:49 UTC (Thu)
by foom (subscriber, #14868)
[Link] (1 responses)
Neither MacOS (mach-o) nor Linux (elf) shared libraries have this issue. They both work fine in this situation, by ensuring that vague linkage symbols are exported and deduplicated across the shared library boundaries by default.
One might expect this would have been addressed in Windows at some point in the last few decades...but it hasn't been.
Posted Jul 15, 2021 13:46 UTC (Thu)
by mathstuf (subscriber, #69389)
[Link]
Posted Jul 18, 2021 18:10 UTC (Sun)
by marcH (subscriber, #57642)
[Link]
OK, so language theory discussions are fascinating (thank you everyone) but now let's get real a bit. Let's pretend I'm managing a software team and I've been asked to get rid of most safety issues in the C++ codebase of our mission-critical application. What -Wold-unsafe-c++ compiler flag do I turn on to make sure my not-all-perfect developers don't make any mistake and stick to "modern C++"? If that compiler flag is not available, what static analyzer(s) should I use? I have practically unlimited budget so I don't mind commercial products. (Even an unlimited budget is unfortunately not enough to hire an elite team of C++ developers who never make any mistake)
> there is no worry about lunch.
I don't think anyone doubts C++ will still make a lot of money after even the youngest people in this discussion are dead, no reason to feel threatened.
Posted Jul 18, 2021 18:49 UTC (Sun)
by marcH (subscriber, #57642)
[Link]
Whether it's true or not, I'm afraid you don't realize how cultish that is perceived.
Ownership and lifetimes
nullptr
”, “never pass null
as reference”, “never use std::move
to return value from function… but don't forget it in other places”… and so on) for C++ have become larger than what Rust demands.Ownership and lifetimes
...perhaps the lifetime of this particular thread has run its course. I don't see anything good coming from this kind of discussion; let's stop here.
Speaking of lifetimes
Ownership and lifetimes
Ownership and lifetimes
Ownership and lifetimes
Ownership and lifetimes
if (x + 100 < x)
you just have to write something like the following: if (std::std::is_signed_v<decltype(x)> ? static_cast<decltype(x)>(static_cast<std::make_unsigned_t<decltype(x)>>)(x) + 100U) < x : x + 100U < x)
float
or double
… or it would be miscomplied because someone used -std=c++20 instead of proper -std=gnu++20… as one of members of pilot Rust program for Android said: I don't feel as satisfied when reviewing Rust code: I always find something to comment on in C++ changes, usually some kind of C++ quirk or a memory management problem. When reviewing Rust changes it makes me uncomfortable if I don't find anything to comment on ("Am I being thorough?").Ownership and lifetimes
Ownership and lifetimes
Ownership and lifetimes
Ownership and lifetimes
Ownership and lifetimes
Concerning integer overflow, the result with a given bit-width is the same for twos-complement arithmetic across all hardware (they all can perform modulo arithmetic, aka wrapping on overflow). And all architectures introduced since 1970 use twos-complement arithmetic exclusively (while, e.g., . So for integer overflow, the behaviour could be just standarized, no need for cop-outs like implementation-defined or implementation-specified. As an example modulo arithmetic has been standardized in Java from the start.
Ownership and lifetimes
Backwards-compatible C compilers in the relaxed Linus Torvals sense (if no one notices, it's not breakage) are possible and desirable.
Ownership and lifetimes
Ownership and lifetimes
Ownership and lifetimes
Ownership and lifetimes
int& pp = *p;
p = nullptr;
cout << pp;
Ownership and lifetimes
You forgot to add Ownership and lifetimes
std::move
to the mix. The fact that after calling foo(std::move(p));
you can have so many possibilities (p
may be destroyed or not destroyed, usable or unusable, etc… and compiler wouldn't ever reveal to you what happened… static analyzers sometimes might) opens up another nice room with so many nice footguns of different sizes…
Ownership and lifetimes
- copy
- assign into (via move or copy)
- call methods on (though many APIs suck and don't provide ways of saying "this makes no sense anymore")
> In that example, `p` cannot be destroyed.
Ownership and lifetimes
p
may be destroyed or not destroyed, p
may be usable or unusable, etc (I hope `p` just means p
in your message and not some new footgun C++ gained while I wasn't looking).p
have a destructor (and said destructor is, of course, the whole reason std::unique_ptr
exists) thus it's non-trivial for the purposes of call which, in turn, means, that destruction of the object pointed by p
still happens in the caller, not callee and, maybe even more importantly, std::unique_ptr
can not be passed in register.std::unique_ptr
shouldn't be used to pass arguments to function and return results from it. Instead you have to use owner<T>
syntax and turn it into std::unique_ptr
in your function and back when you call anything.Ownership and lifetimes
Ownership and lifetimes
Ownership and lifetimes
Ownership and lifetimes
Ownership and lifetimes
> You can get ODR violations by having multiple clashing template specializations, that can be in different parts of the application (for the added fun).
Ownership and lifetimes
-mavx512f
and once without it and you may have nice and long investigation where you would try to understand why minor changes to totally unrelated code creates something that explodes on Ryzen cluster and where clean build either always produces working binaries but incremental builds sometimes lead to crashes.Ownership and lifetimes
Ownership and lifetimes
Ownership and lifetimes
Ownership and lifetimes
Ownership and lifetimes
Ownership and lifetimes
Ownership and lifetimes
Ownership and lifetimes
Ownership and lifetimes
Ownership and lifetimes
Ownership and lifetimes
There is a shortage of developers, not a shortage of code to write. Apparently you can still get paid to fix COBOL code:
https://www.theverge.com/2020/4/14/21219561/coronavirus-p...
Ownership and lifetimes