C++ Stockholm Syndrome


  • Impossible Mission - B

    @pie_flavor said in C++ Stockholm Syndrome:

    @masonwheeler Yes, and they have big runtimes with bytecode.

    Delphi doesn't.


  • Impossible Mission - B

    @gąska said in C++ Stockholm Syndrome:

    Yeah, I totally forgot that on Windows a segfault is SEHan Access Violation is not a Fault. It's much harder (though technically not entirely impossible) to handle it cleanly on POSIXes.

    FTFY, getting to the heart of the problem.


  • Impossible Mission - B

    @gąska said in C++ Stockholm Syndrome:

    Although it doesn't really matter since C++ sidestepshides from the whole issue by making null dereference UB.

    FTFY. "Sidestep" means to cleverly avoid a problem, which is not what UB does.


  • ♿ (Parody)

    @blakeyrat said in C++ Stockholm Syndrome:

    @gąska said in C++ Stockholm Syndrome:

    It was. The @Gąska who wrote it is the one from 3 hours ago who didn't have a chance to read the following posts from @TheCPUWizard and @dkf who explained thoroughly why he was wrong.

    But he wrote it with such certainty! That other gaska must have a malfunctioning brain if he'd state something that's at best on extremely shaky factual ground with absolutely no hint that he might not know what the hell he's talking about. You should go find him and beat him up for making random people on this forum, like me, think you are a total idiot. Send him a black-eye message that, hey, it's not ok to just make up shit and post it as if it were fact.

    Why are you such a dick even when people have admitted they're wrong? Is that just part of your total idiocy?


  • ♿ (Parody)

    @masonwheeler said in C++ Stockholm Syndrome:

    @gąska said in C++ Stockholm Syndrome:

    Although it doesn't really matter since C++ sidestepshides from the whole issue by making null dereference UB.

    FTFY. "Sidestep" means to cleverly avoid a problem, which is not what UB does.

    No, you're just confused as to what he was talking about. In this case, not requiring null checks instead of requiring them by specifying how to handle them.


  • Impossible Mission - B

    @boomzilla said in C++ Stockholm Syndrome:

    requiring null checks instead of requiring them

    You're right, that is confusing! 🚎


  • ♿ (Parody)


  • Impossible Mission - B

    @blakeyrat said in C++ Stockholm Syndrome:

    But he wrote it with such certainty! That other gaska must have a malfunctioning brain if he'd state something that's at best on extremely shaky factual ground with absolutely no hint that he might not know what the hell he's talking about. You should go find him and beat him up for making random people on this forum, like me, think you are a total idiot. Send him a black-eye message that, hey, it's not ok to just make up shit and post it as if it were fact.

    D00d, have you ever heard the expression "quit while you're ahead"?


  • Banned

    @masonwheeler said in C++ Stockholm Syndrome:

    @gąska said in C++ Stockholm Syndrome:

    Yeah, I totally forgot that on Windows a segfault is SEHan Access Violation is not a Fault. It's much harder (though technically not entirely impossible) to handle it cleanly on POSIXes.

    FTFY, getting to the heart of the problem.

    I'm sorry for using a colloquial term for invalid memory reference.



  • @boomzilla said in C++ Stockholm Syndrome:

    Why are you such a dick even when people have admitted they're wrong? Is that just part of your total idiocy?

    I'm just pointing out in my cute little way that maybe the world would be a bit of a better place if people didn't just go around spreading lies everywhere.

    But whatever. I'm a dick, I'm also stupid, etc. We know the drill.


  • Banned

    @masonwheeler said in C++ Stockholm Syndrome:

    @gąska said in C++ Stockholm Syndrome:

    Although it doesn't really matter since C++ sidestepshides from the whole issue by making null dereference UB.

    FTFY. "Sidestep" means to cleverly avoid a problem, which is not what UB does.

    UB is very clever, in the same SFINAE is clever.


  • ♿ (Parody)

    @blakeyrat said in C++ Stockholm Syndrome:

    @boomzilla said in C++ Stockholm Syndrome:

    Why are you such a dick even when people have admitted they're wrong? Is that just part of your total idiocy?

    I'm just pointing out in my cute little way that maybe the world would be a bit of a better place if people didn't just go around spreading lies everywhere.

    No, you weren't. No one was lying.

    But whatever. I'm a dick, I'm also stupid, etc. We know the drill.

    Yes, you are.



  • @boomzilla said in C++ Stockholm Syndrome:

    No, you weren't. No one was lying.

    If you scroll up, you'll see that yes, yes someone was lying.



  • @dkf said in C++ Stockholm Syndrome:

    @gąska said in C++ Stockholm Syndrome:

    High-level C++ is full of smart pointers.

    :sideways_owl:

    I really don't recall seeing lots of code that uses them. Maybe the tools cow-orkers you were working with were keen on using them, but they're really nothing like as commonplace as plain old references.

    Just an observation, well over 70% of the C++ teams I interact with have DRC's to prevent a raw pointer from being used other than as a local variable.

    Also because of lifetime issues (especially in conjunction with custom allocators) even raw references have declined significantly [again, in the teams I interact with] over the past 3-5 years.


  • Impossible Mission - B

    @gąska That's the thing. It's not a colloquial term, it's a technical term with a specific meaning. POSIX is designed with the fundamental idea that invalid memory access in user space is a Fault, a thing that can't be recovered from. (Or at least not easily, because it's a thing that Shouldn't Be Recovered From.)

    This might have made sense in the 1970s, when software was orders of magnitude simpler than it is today and most computer users were computer programmers who knew how to debug a core dump. But those fundamental assumptions are no longer valid. The computing world has changed. The programming world has changed. The error reporting model has changed. But the badly outdated concept of segfaults has not changed with the times.


  • Banned

    @blakeyrat said in C++ Stockholm Syndrome:

    @boomzilla said in C++ Stockholm Syndrome:

    Why are you such a dick even when people have admitted they're wrong? Is that just part of your total idiocy?

    I'm just pointing out in my cute little way that maybe the world would be a bit of a better place if people didn't just go around spreading lies everywhere.

    Hypocrite.



  • @gąska Do I contradict myself? Very well, then I contradict myself, I am large, I contain multitudes.


    Anyway it's not gaska being wrong I object to, a lot of people are wrong all the time. It's that he was so certain he was right that he stated it as 100% iron-clad fact without a hint of doubt. I'm not asking for people to always be right; I'm asking for people to not delude themselves.


  • Banned

    @masonwheeler said in C++ Stockholm Syndrome:

    @gąska That's the thing. It's not a colloquial term, it's a technical term with a specific meaning.

    And a secondary colloquial meaning.

    POSIX is shit.

    No one disagrees with that.


  • Banned

    @blakeyrat said in C++ Stockholm Syndrome

    Anyway it's not gaska being wrong I object to, a lot of people are wrong all the time. It's that he was so certain he was right that he stated it as 100% iron-clad fact without a hint of doubt.

    It used to be a fact back when I last checked. In the meantime the world moved on and JITs aren't as shitty as back when I acquired my knowledge, and I'm happy for it. On the other hand, your claim that GUI code is the only interesting code has never been true.

    Protip: if someone spews bullshit, see if another user hasn't already posted a correction you are about to post yourself.

    Protip #2: it's only a lie if you meant to.


  • ♿ (Parody)

    @blakeyrat said in C++ Stockholm Syndrome:

    @boomzilla said in C++ Stockholm Syndrome:

    No, you weren't. No one was lying.

    If you scroll up, you'll see that yes, yes someone was lying.

    OK, now someone is lying.


  • ♿ (Parody)

    @blakeyrat said in C++ Stockholm Syndrome:

    Anyway it's not gaska being wrong I object to, a lot of people are wrong all the time. It's that he was so certain he was right that he stated it as 100% iron-clad fact without a hint of doubt. I'm not asking for people to always be right; I'm asking for people to not delude themselves.

    PhysicianIdiot, heal thyself!


  • BINNED

    @dkf said in C++ Stockholm Syndrome:

    whereas I think most don't use smart pointers (I don't think I've ever written anything that used those).

    Not even unique_ptr? I use that pretty much everywhere. Unless you allocate on the stack, that's certainly better than new/delete.
    Granted, I scoff most of the time I see a shared_ptr, not because they're not quite useful but because most of the time my co-workers didn't think enough and made the wrong call in using them. That's a people problem, though, not one of shared_ptr .


  • Banned

    @topspin the problem with unique_ptr is that it's significantly harder to mock in tests in some scenarios.


  • BINNED

    @gąska Um, what? Compared to what?


  • Banned

    @topspin shared_ptr.


  • BINNED

    @gąska I'm not sure what scenarios you mean.


  • Trolleybus Mechanic

    I thought I'd share that following this thread has been interesting to follow. It's interesting to hear how modern C++ is playing out in industry. It's also kind of scary to see that so many still use it. Are that many of us working in embedded systems or other similarly constrained systems? Math heavy code probably matters a lot.

    Are any of you using it for "regular" enterprise development for a reason I didn't list above?


  • Banned

    @topspin you cannot easily have another reference to an object inside unique_ptr (I mean, you can, but you can't know if the object is alive if you pass the unique_ptr to some other object or function). I worked with code where we used dependency injection via constructors a lot, and we used shared_ptr's even wwhere unique_ptr's made more sense just because of this issue.


  • BINNED

    @gąska Seems to be the issue that the lifetime/ownership semantics are not well designed, then. Or maybe they are, I'm not saying there's no use case for shared ownership. I don't understand how that is only an issue in your tests, though, and your non-test code would work without sharing.
    (I can't judge any of that, there's usually more subtle details then can be explained in one sentence, so I can only trust you when you say it's needed)


  • Banned

    @topspin said in C++ Stockholm Syndrome:

    I don't understand how that is only an issue in your tests, though, and your non-test code would work without sharing.

    In production code, you just call factory, pass created object to constructor, and forget about it. In tests, you sometimes need a very tight control of what happens with your mocks long after you passed it away.


  • BINNED

    @mikehurley To speak for myself: Our stuff does number crunching, so it's got some performance critical things written in C++ (and interfacing 3rd party libraries in C++). For example, the Eigen library lets you write high-level linear algebra expressions and template magic boils it down to something comparable to hand-written C loops (for small stuff, large stuff calls out to BLAS). Even if you can make Rust do these meta-programming tricks, someone needs to write the libraries first.

    The GUI for it, should you want to use that, is also written in C++ even though you could write that in a different language. The only reasons for that are I (or coworkers, respectively) don't really want to mix languages in one program (you already have the mental burden of understanding C++, mixing languages only adds more), and the Qt GUI is a good compromise between portable and "looks as native as non-native frameworks get".


  • Banned

    @mikehurley said in C++ Stockholm Syndrome:

    Are any of you using it for "regular" enterprise development for a reason I didn't list above?

    Legacy. Both in code and in architects' skillsets.


  • Considered Harmful

    @blakeyrat said in C++ Stockholm Syndrome:

    @boomzilla said in C++ Stockholm Syndrome:

    No, you weren't. No one was lying.

    If you scroll up, you'll see that yes, yes someone was lying.

    You are a moron. Lying is when you intentionally deliver incorrect information. @Gąska specifically said he hadn't realized the opposite was true when he wrote it.


  • Considered Harmful

    @blakeyrat said in C++ Stockholm Syndrome:

    @gąska Do I contradict myself? Very well, then I contradict myself, I am large, I contain multitudes.


    Anyway it's not gaska being wrong I object to, a lot of people are wrong all the time. It's that he was so certain he was right that he stated it as 100% iron-clad fact without a hint of doubt. I'm not asking for people to always be right; I'm asking for people to not delude themselves.

    You are a moron. If you believe something to be true, and have never been contradicted, how would you present it? Experience shows that you personally choose to push the idea as hard as possible until it is very obvious to everyone that you are wrong, at which point rather than eating crow you choose to leave the thread permanently and remain holding the position you started out with.


  • Impossible Mission - B

    @blakeyrat said in C++ Stockholm Syndrome:

    @boomzilla said in C++ Stockholm Syndrome:

    No, you weren't. No one was lying.

    If you scroll up, you'll see that yes, yes someone was lying.

    OK, now you've moved from "quit while you're ahead" to "first rule of holes." :(

    Yes, you were right and Gaska was wrong. But you're losing any and all audience sympathy that that may have gained you by continually harping on this point.



  • @bulb said in C++ Stockholm Syndrome:

    You can do anything in C++, because you can create the low-level implementation yourself.

    That's true, but at least in this case you can wrap it up in something that looks and behaves reasonably to an outside user (i.e., the consumer of the API). That's the difference to the following:

    @dkf said in C++ Stockholm Syndrome:

    … Chiselling it out of raw assembly code if necessary.

    Sure, you can implement "anything" in raw assembly, but in this case, to the user it just looks like an ordinary (un-templated) function that accepts an argument.

    There are probably still a bunch of quality-of-life issues, like that the error messages likely look terrible. But those are also slowly getting ironed out.


  • Banned

    @cvi said in C++ Stockholm Syndrome:

    you can implement "anything" in raw assembly

    Side note: it's funny how often this phrase is repeated, considering that given the average human lifetime and cognitive capacity, this is simply false for a vast majority of code produced today.



  • @gąska Agreed - that's pretty much why I put the quotes around "anything".

    It's especially true if you use any amount of meta-programming. It's easy to end up with a few dozen copies of code that's essentially the same on a high level, but differs a bit deep down in it. Sure, nothing is preventing you from writing the same code in assembly ... but instead of (e.g.) typing up a function call in a few seconds, you've now committed to hours/days/weeks of misery coding up largely identical functions (and I say that as someone who enjoys working with a bit of assembly on occasion).

    Or put differently: sure, you can code anything in assembly, the problem is coding everything in assembly.


  • Discourse touched me in a no-no place

    @topspin said in C++ Stockholm Syndrome:

    someone needs to write the libraries first

    QFFT


  • Banned

    @dkf it's a very important problem, but a problem that pretty much fixes itself over time. Popular languages get libraries for everything, and Rust is popular enough.



  • Was busy, so I'm going to answer some stuff even if I know I was ninja'd already.
    @thecpuwizard said in C++ Stockholm Syndrome:

    re: Constructors and Exceptions..... The reason for the "olde school" of NO, was because an exception in the constructor does not invoke the destructor.

    This is not right. An exception in the constructor will invoke the destructors of the child items already constructed, in reverse order of construction, and this was always true. This required a tiny amount of careful planning around any resource acquisition in the constructor, in that you either can't have throwing operations between the time the resource is acquired and the constructor exits, or you had to immediately hand the resource to a container that handled the clean up for you (smart pointer members for memory allocations, for example).

    People just didn't like exceptions because writing exception safe code was not sufficiently well understood and the mechanism was more expensive in the past, especially for the C coders that were the target of the language. Since constructors can only work properly with exceptions, avoiding constructors that could throw was popular.

    The language was broken before C++11 though, in that without move semantics (which allow you to gut a temporary object that is about to go out of scope instead of copying it) returning objects that managed resources from functions was expensive. The addition of that allowed unique_ptr to replace auto_ptr for example.

    @gąska said in C++ Stockholm Syndrome:

    You shouldn't throw in destructors because throwing causes stack unwind

    Strictly speaking throwing in the destructor is fine, even if the destructor was called in the context of stack unwinding, as long as you don't let the exception leave the destructor. You could have several nested exceptions going on at once and as long as one doesn't escape into the context of another, you're safe. Of course, this is a very rare scenario.

    @masonwheeler said in C++ Stockholm Syndrome:

    @gąska who's destructing them, with no destructor?

    The compiler puts all the machinery in place so that it knows what things have been constructed and need to be destructed, and what is uninitialized and can be ignored. There is no runtime check of "what has been constructed at this point" beyond what the exception mechanism already does. It's no different from how a function knows to run the "catch" block when an exception is thrown. Just imagine that the compiler puts nested try/catches for you as members are constructed.

    @blakeyrat said in C++ Stockholm Syndrome:

    Any feature that requires a human being to implement it without error a thousand times is not a good feature.

    You do it right once per kind of resource (and memory, files, strings, collections of arbitrary types and a host of other types already come with the language), and it works flawlessly every time. The alternative is the "finally" clause, which has to be added manually every time an object of the kind that needs a finally clause is used.

    @thecpuwizard said in C++ Stockholm Syndrome:

    @dkf said in C++ Stockholm Syndrome:

    @gąska said in C++ Stockholm Syndrome:

    High-level C++ is full of smart pointers.

    :sideways_owl:

    I really don't recall seeing lots of code that uses them. Maybe the tools cow-orkers you were working with were keen on using them, but they're really nothing like as commonplace as plain old references.

    Just an observation, well over 70% of the C++ teams I interact with have DRC's to prevent a raw pointer from being used other than as a local variable.

    Also because of lifetime issues (especially in conjunction with custom allocators) even raw references have declined significantly [again, in the teams I interact with] over the past 3-5 years.

    The use I've seen more often (and what I do) is that you might have a local variable or class member be a smart pointer (if you need dynamic allocation), but methods and functions accept references or (rarely, in the case of optional parameters, which you can generally avoid with overloading) pointers as arguments. So even if all your objects live in smart pointers, you'll more often see references because that's what the parameters of most of your functions use. You only pass smart pointers to functions that deal with the lifetime of objects, most functions just assume that the parameters live until the end of the functions and will at most modify their state.



  • @bulb said in C++ Stockholm Syndrome:

    This is cosmetic (and it was an April fool's joke anyway). Also:

    • There are reasons for them: str is a primitive type, so it is lowercase, while library types are uppercase (C# and Java are precedents here), [T] is a primitive too (slight change from C++, C# and Java's T[] to simplify parsing), while the rest is library types. So it just leaves the inconsistency between OsString and PathBuf.
    • In C++ you've got string as owned version of const char * and vector<T> as owned version of T[]? Is that any more consistent?

    So your argument is "they also do it badly so it's okay that we do it badly significantly later"?

    For the record, in C#, int is the same type as System.Int32 and string is the same type as System.String, so that first line is wrong as well.



  • @gąska said in C++ Stockholm Syndrome:

    C++'s smart and raw pointers are nullable, Rust's aren't.

    I think nullable smart pointers were a holdover until we got std::optional. I'd prefer if they weren't nullable.

    @dkf said in C++ Stockholm Syndrome:

    whereas I think most don't use smart pointers

    There's an overuse of std::shared_ptr, so people are using smart pointers, even if they use the wrong kind.

    @dkf said in C++ Stockholm Syndrome:

    but they're really nothing like as commonplace as plain old references.

    Yeah references outnumber smart pointers 10 to 1, but smart pointers are still used quite commonly. PIMPL uses std::unique_ptr and that's a pretty common pattern.

    @mikehurley said in C++ Stockholm Syndrome:

    Are any of you using it for "regular" enterprise development for a reason I didn't list above?

    It has already-done-and-dusted support on many platforms and is good for game development, I doubt many companies will be investing in Rust while it is still so new.



  • @kian said in C++ Stockholm Syndrome:

    Was busy, so I'm going to answer some stuff even if I know I was ninja'd already.
    @thecpuwizard said in C++ Stockholm Syndrome:

    re: Constructors and Exceptions..... The reason for the "olde school" of NO, was because an exception in the constructor does not invoke the destructor.

    This is not right. An exception in the constructor will invoke the destructors of the child items already constructed, in reverse order of construction, and this was always true. This required a tiny amount of careful planning around any resource acquisition in the constructor, in that you either can't have throwing operations between the time the resource is acquired and the constructor exits, or you had to immediately hand the resource to a container that handled the clean up for you (smart pointer members for memory allocations, for example).

    You are right, but so was I (although I could have communicated it better). I was specifically referring to the destructor of the instance where the constructor threw the exception; not the destructor(s) of those members who had been successfully constructed.

    foo()
    {
    p_bar = new bar();
    p_bar->barf(); // throws exception
    }

    ~foo()
    {
    delete p_bar();
    }


  • Discourse touched me in a no-no place

    @gąska said in C++ Stockholm Syndrome:

    a problem that pretty much fixes itself over time

    That makes it sound like self-evolving magic.

    Bullshit. The libraries are there because programmers wrote them. End of.


  • Considered Harmful

    @ben_lubar said in C++ Stockholm Syndrome:

    @bulb said in C++ Stockholm Syndrome:

    This is cosmetic (and it was an April fool's joke anyway). Also:

    • There are reasons for them: str is a primitive type, so it is lowercase, while library types are uppercase (C# and Java are precedents here), [T] is a primitive too (slight change from C++, C# and Java's T[] to simplify parsing), while the rest is library types. So it just leaves the inconsistency between OsString and PathBuf.
    • In C++ you've got string as owned version of const char * and vector<T> as owned version of T[]? Is that any more consistent?

    So your argument is "they also do it badly so it's okay that we do it badly significantly later"?

    There are multiple design decisions at play here. You would be able to call out issues no matter which ones were used. The reason every other language is like this is also because they need to balance multiple design decisions.

    For the record, in C#, int is the same type as System.Int32 and string is the same type as System.String, so that first line is wrong as well.

    What?



  • @pie_flavor said in C++ Stockholm Syndrome:

    For the record, in C#, int is the same type as System.Int32 and string is the same type as System.String, so that first line is wrong as well.

    What?

    What what? [i.e. context for post, it is not clear the reference point of the question]


  • Banned

    @dkf said in C++ Stockholm Syndrome:

    @gąska said in C++ Stockholm Syndrome:

    a problem that pretty much fixes itself over time

    That makes it sound like self-evolving magic.

    Bullshit. The libraries are there because programmers wrote them. End of.

    Yes, but if you take the cynical point of view that only the programming you do yourself or pay for yourself is important, then the ecosystem of the most popular languages just pops up into existence on its own as a byproduct of open source fanatics rewriting the universe over and over again, similar to how oxygen happens to be in the air all the time on its own as a byproduct of plants feeding off sunlight. My argument is that there are enough open source fanatics coding in Rust that it will certainly happen in 5 to 10 years.


  • Banned

    @kian said in C++ Stockholm Syndrome:

    @gąska said in C++ Stockholm Syndrome:

    You shouldn't throw in destructors because throwing causes stack unwind

    Strictly speaking throwing in the destructor is fine, even if the destructor was called in the context of stack unwinding, as long as you don't let the exception leave the destructor.

    When people say "throw", they usually mean "throw to the outside of currently running function". Because the latter is very wordy, and the other kind of throw (one where the exception doesn't leave function) is absolutely uninteresting to the discussion at hand, whatever this discussion might be.


  • Discourse touched me in a no-no place

    @gąska said in C++ Stockholm Syndrome:

    When people say "throw", they usually mean "throw to the outside of currently running function".

    IME, exceptions always pass over function boundaries because the throw machinery always delegates to a function to actually do the dirty deed. But that's totally an implementation detail. (I've not figured out yet why nobody makes the throwing a built-in intrinsic as there's always exactly one correct way to do it for a particular target and the compiler knows what that target is, but that's how it goes.)


Log in to reply