Live data from Hacker News

Popular Myths about C++, Part 2

isocpp.org

91–93 of 93 posts

Re: Popular Myths about C++, Part 2

#91
post #86

Earlier quoted context omitted.

Many modern languages have a convenient solution for those cases as well: Python has the "with" statement combined with context managers; C# has the "using" block with the "IDisposable" interface that does essentially the same thing; even Java recently got its corresponding "try-with-resources". Before those were introduced we had try/finally which works equally well but is slightly more verbose.

Yes, you can do this with try/finally. But if you have an object that has an open file as a member, then you open the file in the constructor, and then use the open file in the member methods, and then... what? You may have a scope that you are exiting where that object becomes irrelevant, but it may be several layers away. Having to close that object's handle in a finally in that scope seems likely to be forgotten a…

That "scope that you are exiting ... several layers away" is where you put the try/finally.

If an object has resources to dispose of (such as an open file), it should implement (to use C# as an example – it looks similar in Python and Java) the IDisposable interface, which allows you to do either:

  MyFileWrapperObject obj = ...;
  try {
    foo();
    bar();
    ...
  }
  finally {
    obj.Dispose();
  }
or:

  using (MyFileWrapperObject obj = ...) {
    foo();
    bar();
    ...
  }
Or to take a Python example from what I'm working on right now:

  with open("something.json") as f:
    data = json.load(f)
The file will automatically be closed at the end of the "with" block. Just like in C#, this feature can be used for any kind of resource, not just files.

Re: Popular Myths about C++, Part 2

#92
post #91

Earlier quoted context omitted.

Yes, you can do this with try/finally. But if you have an object that has an open file as a member, then you open the file in the constructor, and then use the open file in the member methods, and then... what? You may have a scope that you are exiting where that object becomes irrelevant, but it may be several layers away. Having to close that object's handle in a finally in that scope seems likely to be forgotten a…

That "scope that you are exiting ... several layers away" is where you put the try/finally. If an object has resources to dispose of (such as an open file), it should implement (to use C# as an example – it looks similar in Python and Java) the IDisposable interface, which allows you to do either: MyFileWrapperObject obj = ...; try { foo(); bar(); ... } finally { obj.Dispose(); } or: using (MyFileWrapperObject obj =…

> That "scope that you are exiting ... several layers away" is where you put the try/finally.

Yes, I know that it's where you're supposed to put the try/finally... if you remember. Each time. And if you move the action in the finally clause if the variable changes scope or lifetime.

Destructors are considerably cleaner than this approach. You just put the close in the destructor, and let it do its job.

Re: Popular Myths about C++, Part 2

#93
post #67

"My precious language isn't broken! It's not! Not! Not!" Strostrup writes something like this about once a year. There's some denial there. The basic problem with C++ is that it's hard to tell if something really bad is happening. Think of C++ from the view of the maintenance programmer assigned to figure out why a C++ program is crashing intermittently. Or worse, the security expert trying to figure out how a system…

Astonished that your comment got down-voted: it is one of the most insightful here and matches my experience with C++ rather well.

Mixing smart pointers and multi-threading in C++ may result in some nasty surprises that are very difficult to track down and would be impossible with garbage collection, and I'd be curious if Rust would be able to do better here with its fancy type system.

Post reply on HN