Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Author completely misunderstands how to use exceptions and is just bashing them. A lot of what he says is inaccurate if not outwardly incorrect.

Also Bjarne's control of C++ is quite limited, and he is semi-retired, so asking him to "fix his language" is fairly misguided. It's designed by a committee of 200+ people.

Anyway what you want seems to be to not use exceptions, but monads instead. These are also part of the standard, it's called std::expected.



Agreed. Author is trying to mix paradigms. Simplest approach if they want local handling and non-propagation of errors is to just have the file holder not check for open success, and check that manually after construction. Then you get guaranteed closure of file no matter how the function is exited.

  class File_handle {
      FILE *p;
  public:
      File_handle(const char *pp, const char *r)  { p = fopen(pp, r); }
      ~File_handle() { if ( p ) fclose(p); }
      FILE* file() const { return p; }
  };
  
  
  void f(string s)
  {
      File_handle fh { s, "r"};
      if ( fh.file() == NULL ) {
          fprintf(stderr, "failed to open file '%s', error=%d\n", p, errno);
          return;
      }
      // use fh
  }


Goes against "Resource acquisition is initialization" though to have objects which exist but can't be used. (I think that's the relevant pattern?)

However, where the language and it's objects and memory ends and the external world begins, like files and sockets... that's always tricky.


this may lose the value of errno, right?


Yes, it would. It would be trivial to add errno as an instance variable for File_Handle class though.


Kind of the opposite. You lose the fragility and imprecision of and non-extensibility of errno. Good riddance!


> Author completely misunderstands how to use exceptions and is just bashing them. A lot of what he says is inaccurate if not outwardly incorrect.

Do you mind to elaborate what you believe are the misunderstandings? Examples of incorrect/inaccurate statements and/or an article with better explanations of mentioned use cases would be helpful.

> it's called std::expected

How does std::expected play together with all other possible error handling schemas? Can I get unique ids for errors to record (error) traces along functions? What is the ABI of std::expected? Stable(ish) or is something planned, ideally to get something C compatible?


Well, he's using try/catch locally. You're not supposed to handle errors locally with exceptions. The whole point is inversion of control, you manage them at the point where you can do meaningful recovery, which then triggers the cleanup of the whole stack of frames once the exception bubbles up, rather than systematically cleaning up on the normal control flow path.

Regardless, in his example, he could achieve what he wants by wrapping the try in a lambda, and returning either the value from try or nullopt from catch. But clearly, that's just converting exceptions to another error-handling mechanism because he isn't doing it right.

He claimed that not handling an exception causes the program to crash, that's just plain incorrect. To be fair many people use the term "crash" liberally.

std::expected or equivalent is often used with std::error_code, which is an extensible system (error codes are arranged in categories) that among others interops with errno.


> Well, he's using try/catch locally. You're not supposed to handle errors locally with exceptions.

Tell that to Bjarne!


> Do you mind to elaborate what you believe are the misunderstandings?

Exceptional C++, by Herb Sutter is an excellent resource that explains this. It’s quite outdated these days but the core concepts still hold well.

When done well, most of your code can be happy path programming with errors/invalid state taken care of mostly automatically.

However it’s also very easy not to do this well, and that ends up looking like the suggestions the author of the article makes.


Most criticism of C++ comes from people not really into the language. Sure, learning curve might be an issue. But if you are really into C++, there are a lot of things to like about it. At least I do love it. However, only since C++11. Before that, the language felt very strange to me, possibly due to the same effect, I didn't know enough about it.


I'm the opposite. I like C++ but only until C++11. From that point onward, the rules got WAY more complicated, and there's only so much I can/want to hold in my brain at once, I just prefer simpler rules I guess.

Occasionally I do like to use auto or lambdas from C++11 but even then I have to remember more rules for initialization because braces were introduced.


This is true of me as well. I started with C++ in 1991, and I generally knew the language spec quite well (as far as users go) up through C++11.

But now the language packs so much complexity that I can't be sure I understand all of the code I'm looking at.

My usual quality standard for production code is that it doesn't just need to be correct, it needs to be obviously correct. So that's a problem.

Doubly so when the other programmers on the team aren't C++ geeks.


https://godbolt.org/z/363oqqKfv

  struct File_handle {
      static auto Create(std::string const & pp, const char *r) -> std::expected<File_handle, std::error_code> {
          auto p = fopen(pp.c_str(), r);
          if (!p) return std::unexpected(error_code_from_errno(errno));
          return File_handle{p};
      }
      ~File_handle() { fclose(p); }
  private:
      File_handle(FILE * f) : p{f} {} 
      FILE *p;
  };




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: