Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Post
  • Reply
roomforthetuna
Mar 22, 2005

I don't need to know anything about virii! My CUSTOM PROGRAM keeps me protected! It's not like they'll try to come in through the Internet or something!
I can't even tell if the question is "is it a compiler bug to compile this" or "is it a compiler bug to fail to compile this".

Adbot
ADBOT LOVES YOU

roomforthetuna
Mar 22, 2005

I don't need to know anything about virii! My CUSTOM PROGRAM keeps me protected! It's not like they'll try to come in through the Internet or something!

Subjunctive posted:

I’ll take either! I’m not picky.
Then yes!

roomforthetuna
Mar 22, 2005

I don't need to know anything about virii! My CUSTOM PROGRAM keeps me protected! It's not like they'll try to come in through the Internet or something!
Does that mean struct Foo::X should be resolving to the enum that has shadowed the struct? In this context is it even possible to specify struct Foo::struct X?

roomforthetuna
Mar 22, 2005

I don't need to know anything about virii! My CUSTOM PROGRAM keeps me protected! It's not like they'll try to come in through the Internet or something!

Subjunctive posted:

No, AIUI `struct Foo:X` is an explicit tag name lookup which should ignore the enum.
Not sure I get it. Foo::X would refer to the enum then, because it's not explicitly a tag, but then if you had something shadowing Foo, so you have to specify struct Foo, then it would become impossible to reference the enum?

roomforthetuna
Mar 22, 2005

I don't need to know anything about virii! My CUSTOM PROGRAM keeps me protected! It's not like they'll try to come in through the Internet or something!

Xarn posted:

I wish to subscribe to the "rjmccall explains C++" service.
Yeah, that was a really great explanation that semi-ordinary humans can understand. Thanks rjmccall!

roomforthetuna
Mar 22, 2005

I don't need to know anything about virii! My CUSTOM PROGRAM keeps me protected! It's not like they'll try to come in through the Internet or something!

pseudorandom name posted:

C++ turned away from the face of god when it stepped beyond C With Classes.
This but the exact opposite. Classes suck, smart pointers are good.

roomforthetuna
Mar 22, 2005

I don't need to know anything about virii! My CUSTOM PROGRAM keeps me protected! It's not like they'll try to come in through the Internet or something!

Volte posted:

I have some bad news about smart pointers
Yeah yeah, alright, the constructor and destructor part of classes is good too.

roomforthetuna
Mar 22, 2005

I don't need to know anything about virii! My CUSTOM PROGRAM keeps me protected! It's not like they'll try to come in through the Internet or something!
Incidental thing, absl::AnyInvocable is great and it's aggravating that there's not something like this in stdlib until C++21 or something. Finally I can do
code:
absl::AnyInvocable<void()> callback = [p=std::move(some_unique_ptr)]() {...};
rather than
code:
std::function<void()> callback = [tmp_p=some_unique_ptr.release()]() {auto p = std::unique_ptr(tmp_p); ...};
(Which is a memory leak if the callback gets discarded before it is called, and also is a pain in the rear end.)

roomforthetuna
Mar 22, 2005

I don't need to know anything about virii! My CUSTOM PROGRAM keeps me protected! It's not like they'll try to come in through the Internet or something!

Volguus posted:

No complains. No warnings. No ... nothing. At least an "hey moron, are you sure you don't want to publicly inherit that? It's kinda useless otherwise." would have been appreciated. And compiled with Wall, pendantic, everything and cherry-on-top. Clang was happy as a clam.
Can you elaborate on what's wrong with this? It looks okay to me, assuming the Foo was instantiated with make_shared or similar.

roomforthetuna
Mar 22, 2005

I don't need to know anything about virii! My CUSTOM PROGRAM keeps me protected! It's not like they'll try to come in through the Internet or something!

Volguus posted:

It should have been
Oh god, I didn't see it and I've even *done the same thing before* and spent like 40 minutes on it.

roomforthetuna
Mar 22, 2005

I don't need to know anything about virii! My CUSTOM PROGRAM keeps me protected! It's not like they'll try to come in through the Internet or something!

Wipfmetz posted:

So i guess i'll better use a common condition variable to handover work items to worker threads and use a good oldfashioned bool to indicate "no more work incoming, just return from your thread's mainloop, thank you".
If you're using a synced queue to deliver work items and you don't need to interrupt mid-work-item then having an "end" signifier in the queue object, or an "end" work item, makes more sense than having a distinct bool.
(And you shouldn't need any extra objects to wait for the threads to all finish, because there's join for that, assuming when you reach that point you're waiting for all the worker threads or specific worker threads to complete.)

roomforthetuna
Mar 22, 2005

I don't need to know anything about virii! My CUSTOM PROGRAM keeps me protected! It's not like they'll try to come in through the Internet or something!

LLSix posted:

I really like https://en.cppreference.com/w/ as a reference for C & C++. It does a good job of providing in-depth technical details without being as overwhelming as the standards. The cppreference.com site's search tool is terrible but googling cppreference <whatever you need> works pretty well.
I find if I google std::whatever, cppreference nearly always comes up so I don't have to type it.

roomforthetuna
Mar 22, 2005

I don't need to know anything about virii! My CUSTOM PROGRAM keeps me protected! It's not like they'll try to come in through the Internet or something!

Dijkstracula posted:

I've got Opinions on your instructor's decisions there, but I also had Opinions on your other class's instructor's decisions, so I guess at least there's consistency :v:
I first thought "what the heck, you're looking for a leftmost thing, so if you're binary searching and you find a 'missing' you're still gonna have to look at everything further left to make sure none of those are also a 'missing' so what's the benefit?"

Then I thought it was comparing *two* sorted lists, where one has had one item removed, and looking for what the removed item is, which would be a valid use for a binary search provided duplicate entries are not allowed (because everything to the right of target a[i]!=b[i], and everything to the left a[i]==b[i]).

Then I saw that was not the case and I thought for a moment "oh but if you find a missing at 50% and look left and find another at 25% then you don't have to look at the ones in between so there is a saving after all".

Then I realized that no, you still have to look at the 25% to the left (if there's no others missing in there), and if you just did a linear scan from the left you'd look at those and then stop at the first so it would be shorter by one lookup in this case, and there is no case where the binary search reads fewer items than the linear search from left for this algorithm, jesus, is this instructor *intentionally* making nonsense problems, is his entire course like a piece of performance art commenting on blockchain and AI?

roomforthetuna
Mar 22, 2005

I don't need to know anything about virii! My CUSTOM PROGRAM keeps me protected! It's not like they'll try to come in through the Internet or something!

Xerophyte posted:

Nah, binary search works fine here. The proposed algorithm effectively splits the array into two half-sized subarrays, tests (in constant time) if there's a missing number in the left sublist,
Oh, I see, it tests in constant time because len(array) == diff(first, last) if there's no gaps (or duplicates). Yeah, that's not *so* awful then.

roomforthetuna
Mar 22, 2005

I don't need to know anything about virii! My CUSTOM PROGRAM keeps me protected! It's not like they'll try to come in through the Internet or something!
It's not really clear what you're asking for - you want something to happen after something else completes, but on what thread?

If you want it to happen on a specific thread, that waits until that specific thing is done, you want a std::future/promise.

If you want it to happen on a specific thread or pool of threads, that does various pieces of work after various events, you want a dispatcher sort of pattern, where the thing that completes the work pushes a lambda (or some other sort of object indicating the work to be done) onto a queue that wakes up a thread to consume from the queue if one is blocked, or if all the threads are busy then the action will wait 'til one of those threads is done with what it's already doing.

If you want it to do the action on the same thread as the one that was doing the thing you were waiting for to complete, you probably just want to have that thread call a callback when it's done.

I don't think there's a standard library for dispatcher-queue, but it's pretty simple, you guard a deque with a mutex and a condition variable, lock-pushback-signal-release to add work, lock-popfront-release to consume work, if there's nothing to popfront you wait for the condition variable and try again, plus you have to figure out your own termination condition and termination behavior.

roomforthetuna
Mar 22, 2005

I don't need to know anything about virii! My CUSTOM PROGRAM keeps me protected! It's not like they'll try to come in through the Internet or something!

Rocko Bonaparte posted:

Yeah I was thinking of the JavaScript version, specifically:

https://promisesaplus.com/

I think I have seen this acknowledged and used elsewhere. Python's Future class is a future, but let's you attach a callback to run something when the value is filled. I was surprised C++ was cooking something else.
I found this absence of 'then' surprising too when I first encountered C++ promises/futures, but now that I'm comfortable with them I don't understand what it is that you'd expect a future-with-then to do - it really has to do one of:

1. assign the 'then' action to a thread that is waiting for it (that's what it effectively does already)
2. do the 'then' action on the thread that's completing the future (this is just a callback, you don't need a future/promise at all for this, just pass in a std::function and name it "then")
3. post the 'then' action to a threadpool or something (which requires a whole dispatcher setup that doesn't by default exist)
4. start a whole new thread just to handle the 'then' action.

1 is what it already is, 2 doesn't need a future at all, 3 subtly requires a bunch of prerequisites, and 4 is a performance disaster.

I guess the thing that we're familiar with from Javascript-style 'then' is that there's just one thread and at some point it's in a "not doing anything" state, and that's when any async-resolved 'then' actions get resolved. But C++ doesn't have a "not doing anything" state by default, so there's no common place to resolve these things.

roomforthetuna
Mar 22, 2005

I don't need to know anything about virii! My CUSTOM PROGRAM keeps me protected! It's not like they'll try to come in through the Internet or something!

leper khan posted:

Opening on same, closing on its own line. Don't curry
Opening on same, closing on *the start* of a line. Sometimes you close and it's an else or the while of a do-while.
Also, sometimes opening and closing both on the same line if it's short.

roomforthetuna
Mar 22, 2005

I don't need to know anything about virii! My CUSTOM PROGRAM keeps me protected! It's not like they'll try to come in through the Internet or something!

Presto posted:

No it isn't because those go on the line after the brace. :colbert:
Yes it still is sometimes an else after a brace, you're just saying you should format that like a maniac. You appear to be suggesting this monstrosity?
code:
if (banana) {
  doStuff();
}
else {
  doOtherStuff();
}

roomforthetuna
Mar 22, 2005

I don't need to know anything about virii! My CUSTOM PROGRAM keeps me protected! It's not like they'll try to come in through the Internet or something!

ShoulderDaemon posted:

When I first started at my current employer, one of the simulators I became owner of was consistently formatted like this:
code:
if
    (foo) doStuff();
    else
{   doOtherStuff();
    doSomethingElse(); }
I think we should all standardize on this, to better reflect the actual quality of the code.

roomforthetuna
Mar 22, 2005

I don't need to know anything about virii! My CUSTOM PROGRAM keeps me protected! It's not like they'll try to come in through the Internet or something!

epswing posted:

I've got an C++ app (MFC running on Windows 10/11) every few seconds polling (via libcurl) an ASP.NET site running on IIS on the same PC. I'd like to stop polling and reverse this communication, by having the ASP site signal the C++ app somehow. The content of the signal is small (a few bytes) and not frequent (once every few seconds). SignalR comes to mind but the .NET Framework (i.e. pre .NET Core) cpp SignalR client library seems abandoned. Named pipe? Socket? MSMQ? Is there a recommended/modern mechanism for this?
If the thing being polled is a web server then the way to do that is typically either "long-polling" or websockets. Long-polling is significantly easier to implement but maybe easier to make a mistake with.

roomforthetuna
Mar 22, 2005

I don't need to know anything about virii! My CUSTOM PROGRAM keeps me protected! It's not like they'll try to come in through the Internet or something!

Dijkstracula posted:

(I've seen this done with a bunch of different mechanisms: UNIX domain sockets, UDP datagram, long-polling over TCP, websockets. All things being equal, none are any better or worse than any other, but certain choices (websockets, I imagine, in particular) might be more difficult to do in MFC-land.)
I would argue that UDP datagram is worse in most situations because you *generally* don't want to miss messages, or implement your own thing for detecting and re-sending potentially missed messages. And if we're talking like the level of UDP datagram then there isn't long-polling over TCP, there's just a TCP socket, long-polling is for http (which, yes, is generally over TCP, but it would be a weird way to describe it). Other than that though, yes.

Also this now has me wondering would long-polling over http3 (which is not over TCP) make sense or not.

Edit: also realizing maybe long-polling wasn't quite the right term for what I meant, that's generally for notification of rare updates. HTTP subscription for fast small updates is *similar*, but instead of one-poll one-eventual-reply, it's one-poll, stream-replies, re-poll-when-client-or-server-timeout-nears. I don't know if there's a name for that. It also has a good chance of playing poorly with proxies.

roomforthetuna fucked around with this message at 23:43 on Nov 22, 2023

roomforthetuna
Mar 22, 2005

I don't need to know anything about virii! My CUSTOM PROGRAM keeps me protected! It's not like they'll try to come in through the Internet or something!
Joke answer for interprocess communication, grpc.

Not a joke in that it wouldn't work, but a joke in that every 3 months you'd have to restructure your entire build system because Google decided to change protobuf and/or absl and/or grpc again in a not-backwards-compatible way AGAIN and it's a massive pain in the arse.

roomforthetuna
Mar 22, 2005

I don't need to know anything about virii! My CUSTOM PROGRAM keeps me protected! It's not like they'll try to come in through the Internet or something!

Subjunctive posted:

Wait, I thought protobuf was really stable?
Protobuf is definitely not really stable, they keep changing build APIs all the time, and they added the 'Any' type which potentially makes the "stable" serialization unstable again, and the switch from proto2 to proto3 changed a lot of things (especially cross-language compatibility) and the addition of map types was the thing that originally destabilized serialization, especially for golang, and the golang API changed its implementation of the oneof type, and the javascript protogen moved out of the main library and then the *next* update of the main library was incompatible with the separated-out google-owned javascript library for over a year, to pick just a few examples of things that have made my life difficult that I happen to remember.

quote:

But also, just because Google does something doesn’t mean you have to upgrade unless they’re fixing something that’s an issue for you. Your software works, you can leave it alone.
As for not needing to upgrade, yeah, this was a work rant really - at my work we have a monorepo and use envoy, and updating envoy requires us to update absl, protobuf and grpc (and other things too), each of which typically breaks everything else so it's a huge pain in the rear end every time.

(Having any dependency that uses tensorflow would be another thing that probably would force you to update the whole chain of google libraries.)

Though actually not just a work rant - I moved my personal project from protobuf to flatbuffers in the hope of escaping google-churn, and even that wasn't stable so I ended up just writing my own serialization API that's better for my purposes in literally every way anyway. (Smaller generated code, simpler API, smaller serialized size, and embedded types.)

roomforthetuna
Mar 22, 2005

I don't need to know anything about virii! My CUSTOM PROGRAM keeps me protected! It's not like they'll try to come in through the Internet or something!

Jabor posted:

None of those things you've mentioned change the wire format though? Like, if you haven't changed the proto definition itself, you can upgrade the libraries and then keep reading protos serialised by the old version (and serialise protos that the old version can read). Unless you're using the weirdo "serialise to json instead of to the actual proto wire format" thing, I dunno how that one works.

proto3 is only a big change if you actually choose to use it, and no-one's forcing you to do that - you can keep using your existing proto2-formatted definitions and they still compile to the same thing.
I didn't say they changed the wire format. My point is the library keeps changing API and build stuff so it will absolutely be a pain in the rear end every time if you have some other thing that has a dependency on it that you have to update, and a triple pain in the rear end if you have two or more things that depend on it because inevitably one of them will update before the other and until they sync up you have to build with two different versions of the proto library in the same environment, or patch one of your dependencies yourself so it will build against a different version, and it absolutely sucks balls.

Google pretty explicitly does not give a poo poo about open source clients of their libraries except *maybe* abseil, and it shows in how they migrate APIs with no kind of bridge deprecation period. Or, perhaps the best example, in how they literally had their protobuf open source library become build-incompatible with the protobuf-javascript open source library that is also owned by Google, and stay that way for over a year, with a front-page readme on the github repo that straight up said as a gently caress you "this is broken, we have this working internally and don't have funding to support the open source version, we expect to have it fixed by November 2022", up until about 2 weeks ago (in November 2023) when it actually updated.

So anyway, it was a throwaway joke about overkill using grpc for a task where it wouldn't be necessary or helpful, because it's front-of-mind for me because I've been doing a version update *for over three loving weeks* it's so bad this time. The serious comment I'm making is "if you don't have to, and there's not a really big benefit, don't use a Google library because the future cost is almost certainly higher than it would be for other similar libraries."

Edit: We all know this about google products in general of course, but for some reason it remains a bit shocking when it happens with libraries.

roomforthetuna fucked around with this message at 03:28 on Nov 24, 2023

roomforthetuna
Mar 22, 2005

I don't need to know anything about virii! My CUSTOM PROGRAM keeps me protected! It's not like they'll try to come in through the Internet or something!

Jabor posted:

I guess I misunderstood what you meant by stable serialisation.
Oh, I see. Yeah, that's a different thing entirely from what I was originally talking about, but is also a thing! What I'm talking about there is:

1. in old proto, you *could* have the same message serialized different ways, but if you had the message in native form and serialized it, you would always get identical output bytes. This means you could compare two messages with a memcmp of the serialization, or hash it, for example.
2. when map types were added, this changed because a map is an implicitly unordered type. In golang, map types became *intentionally unstable* for serialization, which at the time intentionally broke many existing unit tests even inside google.
3. to compensate for this, a "serialize deterministically" option was added to various serializers, so you could optionally get back the behavior from timepoint 1. This would deterministically sort map types when serializing.
4. when the "any" type was added, it broke the behavior of that option, but the option still exists, making the behavior quite surprising. The TextFormat serializer will, in the current version, serialize deterministically even through Any types, if you set the right options, but the binary serializer does not have the options to do this; if there's a map type inside the message inside an Any field, or if the Any field was previously serialized a different way (as has been valid all along), asking for deterministic serialization will get you nondeterministic serialization.

For a fun sequence of events around this, here's a little adventure through the years:
https://github.com/envoyproxy/envoy/pull/5814 - "oh no it's not deterministic"
https://github.com/protocolbuffers/protobuf/issues/5668 - "you can make it deterministic" "oh yeah, okay, we did that, we're good"
https://github.com/protocolbuffers/protobuf/issues/5731 - "actually no we're not, they still aren't deterministic" "oh yeah, Any fields aren't supposed to do that. Try just not using them."
https://github.com/envoyproxy/envoy/commit/647aea1d97be232930306183f94536d3e1f7d9ed - "aha, text formatting supports this"
https://github.com/envoyproxy/envoy/pull/30761 - "yeah but the performance of that loving sucks"

roomforthetuna
Mar 22, 2005

I don't need to know anything about virii! My CUSTOM PROGRAM keeps me protected! It's not like they'll try to come in through the Internet or something!

Subjunctive posted:

I don’t think any of our other in-use serializers are guaranteed to be deterministic, so that’s probably fine for us. Weird that they want it to be deterministic but also not?
Also weird, in the C++ library there is a GetRepeatedRef<type> template for repeated fields, but no Get<type> or GetRef<type> for non-repeated fields which makes writing handlers for that frustrating (you have to either repeat poo poo a lot or use gross macros so that you can do like int32_t x = reflection.GetInt32(args) and uint32_t x = reflection.GetUint32(args). I don't think there's any reason not to template - it would also be a nice place to add Get<string_view>, instead of making the existing interfaces change from std::string& to string_view in a way that breaks existing code!)

roomforthetuna
Mar 22, 2005

I don't need to know anything about virii! My CUSTOM PROGRAM keeps me protected! It's not like they'll try to come in through the Internet or something!

Subjunctive posted:

Sorry, I was typing while distracted and forgot to add that per my source they are “not very close”.

I could definitely see the same team doing both though, and that would probably be my instinct rather than staffing two teams each with all the language and platform expertise. It seems like the rate of change to that stuff is (should be?) low and want to evolve in a coordinated way, but maybe that’s a misconception.
This is actually a good reason for them to be separate teams, in that changing protobuf should be as painful within google as it is outside, and that pain should be screamed about to discourage disruptive changes.

Unfortunately it doesn't actually work like that because neither of them use the open source repository, they both build in a shared monorepo so the changes are easy and simultaneous, the victim team doesn't even have to fix it themselves, and any breakages are just foisted onto open source users later without much of a care.

roomforthetuna
Mar 22, 2005

I don't need to know anything about virii! My CUSTOM PROGRAM keeps me protected! It's not like they'll try to come in through the Internet or something!

nelson posted:

The vector is just the complete data set initialized from a file. Nothing is added or deleted once the file loading is done, although the objects pointed to can be modified in a dynamically determined order, which is what the queue is for.

There’s really no “need” to use smart pointers at all but I’m an old guy trying to understand best practices when it comes to modern C++ development.
If the vector outlives all other users of the things (i.e. it is the undisputed owner of that data), then std::unique_ptr in the vector and std::reference_wrapper in the list would be what the open source community I participate in would recommend. reference_wrapper is basically the same as a pointer at runtime, but semantically different in that it's invalid for it to be nullptr, which if your list is always pointing at something means this type would be more accurate. However, it's also syntactically more painful to use than a bare pointer, and mostly doesn't even act like a reference. (I found it pretty disappointing when I first used it, IMO it would be more accurately named "not_null_pointer".)

shared_ptr and weak_ptr carry a performance cost that in some circumstances can be significant. I tried turning a horrible construct that used unique_ptr with a custom destructor to make some values shared singletons and others deleteable, into a shared_ptr so the singletons could just duplicate the existing pointer and the deleteable ones would be allocated, because the weird construct was hideously hard to follow and had a whole bunch of issues with having to declare specified destructors everywhere, but the performance with shared_ptr was 3x slower. I did manage to clean it up in the end, but mostly leaving the underlying structure alone and just putting some extra wrappers around it to make it less gross at the use-sites.

roomforthetuna fucked around with this message at 01:45 on Dec 13, 2023

roomforthetuna
Mar 22, 2005

I don't need to know anything about virii! My CUSTOM PROGRAM keeps me protected! It's not like they'll try to come in through the Internet or something!

OddObserver posted:

It looks like std::shared_ptr requires barriers on refcount decrement, plus also potentially another allocation if you are holding it wrong.
Yeah, the barriers were most likely the big cost in the specific context. std::move was being done in all the right places to avoid the unnecessary costs, and there's no getting around the one additional allocation if you're actually using it shared-pointerily. The point is shared_ptr (and by extension weak_ptr since it turns into a shared_ptr before you can use it) is significantly more expensive than unique_ptr (which is performance-wise practically identical to a bare pointer) in both time and space.

There is a fairly common construct, the refcounted-pointer, which is like shared_ptr without the barriers, but it doesn't exist in the standard library. And it still wouldn't be necessary or useful for the context under discussion. I should probably have tried using that in the context I was talking about though, it probably would have been the best of both worlds, and there was already an implementation of it in the project in question.

Edit: the other nice thing about mostly using unique_ptr is it gets you into habits that are beneficial for shared_ptr too, because you *can't* forget to std::move a unique_ptr, versus if you don't std::move (when you could have) a shared_ptr then you end up performing extra increments and decrements and barriers.

roomforthetuna
Mar 22, 2005

I don't need to know anything about virii! My CUSTOM PROGRAM keeps me protected! It's not like they'll try to come in through the Internet or something!

Plorkyeran posted:

std::make_shared avoids the extra allocation, at the cost of making the allocation stay alive as long as there's any weak_ptrs pointing at it.
I was meaning in the context of the one that's being used as a singleton, where every instantiation of a "copy" has to allocate an additional shared_ptr object. But now that I think about it that's true of the singleton-special-unique-ptr-with-do-nothing-destructor too. And both of those are probably on the stack anyway.

But that's interesting, I didn't realize weak_ptrs keep the allocated object alive if it's been made with make_shared. It makes sense now you say it, and I guess is mostly unimportant since the weak_ptrs should all eventually get destroyed too anyway, but could be important for a big enough object.

roomforthetuna
Mar 22, 2005

I don't need to know anything about virii! My CUSTOM PROGRAM keeps me protected! It's not like they'll try to come in through the Internet or something!

Volguus posted:

Aaah, ok, now I understand the initial statement. Yes, the object is destructed and destructor is called and all, but you're right, the drat thing is still there somewhere. Yeah, you don't want weak_ptr's to be alive for too long.
Yeah, I guess it's not a big deal if it's some tree-shaped object with a narrow trunk, because it would do the destructor at least so only the "stump" of the tree would persist, but if it was a broad object like shared_ptr<std::array<char, 1024*1024>> then the weak_ptr to an object made with make_shared would be keeping that megabyte allocated.

roomforthetuna
Mar 22, 2005

I don't need to know anything about virii! My CUSTOM PROGRAM keeps me protected! It's not like they'll try to come in through the Internet or something!

Nalin posted:

I was mainly complaining about how that specific, very important bit of functionality is something that isn't really known or noticed unless you are reading implementation notes. Especially since many places that teach it basically say its a way to avoid having to ever write "new" in your code. It's just another annoying thing you have to keep in your mind.

EDIT: I guess I'm just annoyed that two valid implementations are not easily distinguished between the two and you have to remember which way of creating the object results in which implementation.
If you're just using it as a way to avoid writing "new" then you should *always* be using unique_ptr which doesn't really have any of these gotchas, it literally just performs identically to a bare pointer but forcing you to be more careful about ownership. shared_ptr just gets wacky because the stuff its doing is wacky, and it's trying to be everything for everyone (e.g. having barriers in it so it can work with threads, which can be really unnecessarily poor for performance if the pointer ownership doesn't actually traverse threads).

roomforthetuna
Mar 22, 2005

I don't need to know anything about virii! My CUSTOM PROGRAM keeps me protected! It's not like they'll try to come in through the Internet or something!

rjmccall posted:

std::shared_ptr is definitely a much more abstract type than you might expect: it can either take ownership of an existing allocation or co-allocate, it defaults to using the standard allocator but can work with an arbitrary one, it supports a bunch of related features around weak references, etc. All of those choices have costs that get paid at runtime, and modern designers would probably force that all to be statically explicit. And maybe they’d be right to; I dunno, though.
It's definitely nice to have a simple does-everything option available for when you're *not* in a particularly performance-critical context, like most things are not. I appreciate the shared_ptr for that, but I do wish there were some other abstractions in the standard library too, especially a refcounted pointer that doesn't support weak or thread safety. (Supporting co-allocation or not is fine since there's no additional performance cost in being capable of both.)

Edit: vvvv I meant supporting "co-allocation or not", like it should be capable of doing both - there's a performance cost in *doing* the worse one, but supporting both means you only do the worse one when that's what the user of the library asked for. As a contrast to supporting thread-safety, weak_ptr or shared_from_this have a performance cost whether you're using them or not. [or, depending on implementation, have no performance cost to not use but are performance-awful when you do use them]

roomforthetuna fucked around with this message at 13:58 on Dec 15, 2023

roomforthetuna
Mar 22, 2005

I don't need to know anything about virii! My CUSTOM PROGRAM keeps me protected! It's not like they'll try to come in through the Internet or something!

Xarn posted:

I actually ended up writing more about this here.
Today I learned <=> is a C++ operator.

roomforthetuna
Mar 22, 2005

I don't need to know anything about virii! My CUSTOM PROGRAM keeps me protected! It's not like they'll try to come in through the Internet or something!

Xarn posted:

Yep, it is called the spaceship operator and because this is C++, it returns one of std::strong_ordering, std::weak_ordering, and std::partial_ordering. These are not to be mistaken with std::strong_order, std::weak_order and std::partial_order :v:
Thanks for making a thing that seemed neat into a thing that seems horrifying.

roomforthetuna
Mar 22, 2005

I don't need to know anything about virii! My CUSTOM PROGRAM keeps me protected! It's not like they'll try to come in through the Internet or something!

Plorkyeran posted:

It's certainly not the most elegant thing out there, but it lets algorithms like sorting that need a strong ordering to express that in the type system. std::strong_order and std::strong_ordering both existing is awkward but they are at least things that go together and just not totally unrelated types.
Oh, I see, the idea is you can have separate overrides of the operator for "fast and loose" or "slow and strong" ordering and sort algorithms can select (or be selected) based on what's available/better. That's not so bad.

roomforthetuna
Mar 22, 2005

I don't need to know anything about virii! My CUSTOM PROGRAM keeps me protected! It's not like they'll try to come in through the Internet or something!

Nalin posted:

lol, watch out though, because if you explicitly default the destructor, copy-constructor, or copy-assignment operator, then the compiler won't implicitly generate a move constructor or move assignment operator for you.
This is probably my most hated thing about C++. I can at least rationalize *why* it would do anything else annoying, but this one is annoying *and* nonsensical.

roomforthetuna
Mar 22, 2005

I don't need to know anything about virii! My CUSTOM PROGRAM keeps me protected! It's not like they'll try to come in through the Internet or something!

leper khan posted:

backward compatibility before move. if you dont have move and you do have copy, you may be in a codebase that doesnt know about move, and only expects copy. so moving and invalidating will likely break code. esp for libraries written to old standard interoperating with newer code.
Ah, thank you, that does make sense of it, and now I even appreciate it, backwards compatibility is a wonderful thing. (That grpc, protobuf and other things mostly caused by google don't give enough of a gently caress about.)

Adbot
ADBOT LOVES YOU

roomforthetuna
Mar 22, 2005

I don't need to know anything about virii! My CUSTOM PROGRAM keeps me protected! It's not like they'll try to come in through the Internet or something!
I prefer old-school Makefiles for having full control over everything, but if I had to use a modern thing, I like bazel a lot more than CMake.

The learning curve to get something just generally working isn't too bad, but once you start getting into needing to be able to import a dependency that isn't something you own, yeah, it can get pretty gnarly. That's probably true of any system.

  • 1
  • 2
  • 3
  • 4
  • 5
  • Post
  • Reply