Live data from Hacker News

Orthodox C++ (2016)

bkaradzic.github.io

141–150 of 238 posts

Re: Orthodox C++ (2016)

#141

Earlier quoted context omitted.

My favorite was the regex engine that was implemented using C++ operator overloading. The author was very proud of it, but you could not tell what code was regex code and what code was math code. I went to some lengths with D to discourage such abusive operating overloading practice.

Thank you. I don't even use D, but appreciate all efforts to socialize sane programming practices.

Thank you for the kind words! I recently did a presentation at Yale where I felt free to ridicule some insane practices, and how to do a better job.

Slides:

https://walterbright.com/ElegantD.pdf

Re: Orthodox C++ (2016)

#142

Earlier quoted context omitted.

> build a fort to deflect the random exceptions they'll throw at you Sounds like you hate exceptions, right? In which case why do you handle them at all? Just leave them all unhandled and suddenly every exception is a crash. Which is really no different from someone choosing to terminate. Which you have to worry about even without exceptions. > if you have a C++ code base yet somehow have enough time and energy to wr…

> Sounds like you hate exceptions, right? In which case why do you handle them at all? One of the problems with exceptions is it’s utterly impossible to know if a given function call can return exceptions and if so what they are. My code DOES want to handle errors. Exceptions are, imho, a very very poor way to report errors. Python is the bloody worst because I never effing know what the hell any damn function can th…

Exceptions aren't meant to report errors, just in general. That's a misuse of them. Exceptions are meant to be thrown when a contract cannot be fulfilled. Yes, you're unable to know what exceptions a function may throw. That's the way it should be, because exceptions aren't supposed to be part of the function's contract.

For example, you're implementing an arithmetic operator and have reached an erroneous state, but the arithmetic type doesn't have an error value, the only way to communicate the error is by throwing. Another example: you've specified that a function must always succeed, but later on you find a case where the function cannot succeed. Instead of fixing all the possible call sites, throw an exception. All those callers could not have handled the error anyway, because they were coded under the assumption that no error would happen at that point. Throwing an exception and letting it unwind the stack way up (perhaps even all the way up to main()) is the sensible solution, because at that point you've reached a situation with no reasonable way for that code to handle.

Saying that you prefer Result over exceptions is like saying that you prefer strings to functions. They do different things. If you like Result, nothing prevents you from implementing a C++ equivalent.

Re: Orthodox C++ (2016)

#143

Earlier quoted context omitted.

> build a fort to deflect the random exceptions they'll throw at you Sounds like you hate exceptions, right? In which case why do you handle them at all? Just leave them all unhandled and suddenly every exception is a crash. Which is really no different from someone choosing to terminate. Which you have to worry about even without exceptions. > if you have a C++ code base yet somehow have enough time and energy to wr…

> Sounds like you hate exceptions, right? In which case why do you handle them at all? One of the problems with exceptions is it’s utterly impossible to know if a given function call can return exceptions and if so what they are. My code DOES want to handle errors. Exceptions are, imho, a very very poor way to report errors. Python is the bloody worst because I never effing know what the hell any damn function can th…

> One of the problems with exceptions is it’s utterly impossible to know if a given function call can return exceptions and if so what they are.

Could you please explain how exactly you know if a function might abort?

And how you figure out exactly which error codes a function might return if it does return an error?

And why/how your techniques for figuring out the above don't work for exceptions?

> Python is the bloody worst because I never effing know what the hell any damn function can throw or return. It’s so so frustrating.

No, it's pretty possible. Virtually any interesting function you call can throw AttributeError or TypeError, if nothing else, simply by virtue of you passing an object of the wrong type or behavior.

"But I don't mean those particular exceptions! I don't care about them." Well yeah that's kind of the point. If you can pretend that problems you don't know how to handle don't exist, then you can pretend the same for exceptions and errors. You're not supposed to care about the entire universe of possible error conditions; it's not only impossible but also you wouldn't be able to handle all of them anyway. You handle everything you can reasonably handle and then let the rest propagate, not the other way around. Same for error codes and exceptions.

"But the documentation would tell me which error codes I care about!" Well it can do that for exceptions too. If the documentation sucks then bring it up with the API developer not the language developer.

> But I’ll take Rust results over exceptions 10,000% of the time. Not even a question.

Sure, feel free to do that. Or use error codes in C++, whatever you prefer. Not like I'm trying to turn this into a Rust vs. C++ debate.

Re: Orthodox C++ (2016)

#144

Earlier quoted context omitted.

> Sounds like you hate exceptions, right? In which case why do you handle them at all? One of the problems with exceptions is it’s utterly impossible to know if a given function call can return exceptions and if so what they are. My code DOES want to handle errors. Exceptions are, imho, a very very poor way to report errors. Python is the bloody worst because I never effing know what the hell any damn function can th…

Exceptions aren't meant to report errors, just in general. That's a misuse of them. Exceptions are meant to be thrown when a contract cannot be fulfilled. Yes, you're unable to know what exceptions a function may throw. That's the way it should be, because exceptions aren't supposed to be part of the function's contract. For example, you're implementing an arithmetic operator and have reached an erroneous state, but…

> Exceptions aren't meant to report errors, just in general. That's a misuse of them. Exceptions are meant to be thrown when a contract cannot be fulfilled. Yes, you're unable to know what exceptions a function may throw. That's the way it should be, because exceptions aren't supposed to be part of the function's contract.

I don't think these are true? What about std::vector::at(), std::optional::value(), etc.? And then there's std::system_error.

Re: Orthodox C++ (2016)

#145

Earlier quoted context omitted.

> build a fort to deflect the random exceptions they'll throw at you Sounds like you hate exceptions, right? In which case why do you handle them at all? Just leave them all unhandled and suddenly every exception is a crash. Which is really no different from someone choosing to terminate. Which you have to worry about even without exceptions. > if you have a C++ code base yet somehow have enough time and energy to wr…

> Which is really no different from someone choosing to terminate. If you std::abort(), you'll get a useful stack trace in the core dump. If you crash from an unhandled exception, you don't. That's a pretty huge difference and is one of the reasons exceptions suck.

Just FYI, finally in C++ you can add a top-level exception handler and call boost::stacktrace::from_current_exception (https://www.boost.org/releases/1.85.0/), and get a stack trace on exit as helpful as in Python or Java.

Re: Orthodox C++ (2016)

#146

Earlier quoted context omitted.

> Sounds like you hate exceptions, right? In which case why do you handle them at all? One of the problems with exceptions is it’s utterly impossible to know if a given function call can return exceptions and if so what they are. My code DOES want to handle errors. Exceptions are, imho, a very very poor way to report errors. Python is the bloody worst because I never effing know what the hell any damn function can th…

> One of the problems with exceptions is it’s utterly impossible to know if a given function call can return exceptions and if so what they are. Could you please explain how exactly you know if a function might abort? And how you figure out exactly which error codes a function might return if it does return an error? And why/how your techniques for figuring out the above don't work for exceptions? > Python is the blo…

Functions aborting is not something I’ve ever really had to think about. Exception heavy codebases it’s something I have to ALWAYS think about.

Error codes are pretty bad. Global error code is awful. An error enum is pretty nice.

So here’s the thing. I’ve been a professional C++ programmer for 20 years. Not once have I ever worked in a codebase that used exceptions. It’s fine. Occasionally I use a thirdparty library that does use exceptions and it’s bloody awful.

Re: Orthodox C++ (2016)

#147

Earlier quoted context omitted.

Exceptions aren't meant to report errors, just in general. That's a misuse of them. Exceptions are meant to be thrown when a contract cannot be fulfilled. Yes, you're unable to know what exceptions a function may throw. That's the way it should be, because exceptions aren't supposed to be part of the function's contract. For example, you're implementing an arithmetic operator and have reached an erroneous state, but…

> Exceptions aren't meant to report errors, just in general. That's a misuse of them. Exceptions are meant to be thrown when a contract cannot be fulfilled. Yes, you're unable to know what exceptions a function may throw. That's the way it should be, because exceptions aren't supposed to be part of the function's contract. I don't think these are true? What about std::vector::at(), std::optional::value(), etc.? And t…

>std::vector::at(), std::optional::value()

Both functions must return T &. If the vector is not long enough, or the object is not set, then returning a T & is impossible. So we have a function that has already been called and which must return something valid, and cannot return something valid. The only two ways to resolve this contradiction is to throw, or to terminate.

(Well, you could also trigger undefined behavior like operator[]() and operator*(). No comment.)

>And then there's std::system_error.

And what am I supposed to conclude from the existence of a type?

Re: Orthodox C++ (2016)

#148

Earlier quoted context omitted.

Its behavior is dictated by the language. The context of this thread is that someone stated that the C++ standard library sucks, and someone replied to them saying that it's just some implementations that suck, but that's separate from the language. The point I'm trying to make, in response, is that it is about the language. It's not just "some" implementations - there is no implementation of the C++ standard library…

In my reading, they didn't say it's due to bad implementations, though. They were trying to separate the standard into two parts, the one about the language syntax and semantics, and the one about the standard library. And I think this is a fair separation actually. But that doesn't make the core language any better ;-)

Hm. You're probably right.

Re: Orthodox C++ (2016)

#149

Earlier quoted context omitted.

> Sounds like you hate exceptions, right? In which case why do you handle them at all? One of the problems with exceptions is it’s utterly impossible to know if a given function call can return exceptions and if so what they are. My code DOES want to handle errors. Exceptions are, imho, a very very poor way to report errors. Python is the bloody worst because I never effing know what the hell any damn function can th…

Exceptions aren't meant to report errors, just in general. That's a misuse of them. Exceptions are meant to be thrown when a contract cannot be fulfilled. Yes, you're unable to know what exceptions a function may throw. That's the way it should be, because exceptions aren't supposed to be part of the function's contract. For example, you're implementing an arithmetic operator and have reached an erroneous state, but…

> Throwing an exception and letting it unwind the stack way up (perhaps even all the way up to main()) is the sensible solution

No. I would never in a million years do this.

If the API is that a function is infallible and then I decide that it’s a fallible function then that’s a pretty major change and I’m just gonna have to update all the call sites to deal with a fallible return result.

Saying throw an exception and bubble up to main provides just about zero value. Might as well just call std::abort. Which is also something I would never do.

> Saying that you prefer Result over exceptions is like saying that you prefer strings to functions. They do different things.

So here’s the thing. In 20+ professional years as a C++ dev I have never ever once worked in a codebase where exceptions were used. Certainly never in first party code. Only when dealing with annoying thirdparty libraries that leveraged them.

I think your comment “contract can’t be fulfilled” is cheating. No. You’ve simply made a new contract and the new contract is that under certain cases an error is returned in the form of an exception.

Re: Orthodox C++ (2016)

#150
post #125

Earlier quoted context omitted.

doesn't require iostream.

fair, but it generates a std::string .. if you want to see it, what are you going to do with it? use .c_str() ??

If you want to see it where? If you want a string you've got a string. If you want to write text to something resembling file I/O (e.g. stdout) then std::print and std::println are what you need instead of std::format

Stroustrup's I/O Streams is a weird dead-end C++ technology. Bjarne is probably never going to get over it, but everybody else should forget about it ASAP.

Post reply on HN