Live data from Hacker News

Bjarne Stroustrup – The Essence of C++ [video]

channel9.msdn.com

51–60 of 85 posts

Re: Bjarne Stroustrup – The Essence of C++ [video]

#51

I look at Java code and it horrifies me. Java is great if your resource is memory. It turns into a horrible unsafe mess the moment your resources are not memory. //C++ RAII goodness. void foo() { conn.open(); file.open(); printer.activate(); //do stuff } //Java's lack of RAII is disturbing void foo() { try{ conn.open(); file.open(); printer.activate(); //do stuff } catch(Exception e) { } finally{ try { conn.close();…

Java 7 introduced a new language construct, called the try-with-resources statement, for automatic resource management:

    void foo() {
        try (open file or resource here) {
            // do stuff
        }
        // after try block, resource will close automatically
    }
This works with non-memory resources such as files, streams, sockets, and database connections.

Re: Bjarne Stroustrup – The Essence of C++ [video]

#52
post #9

Earlier quoted context omitted.

The point of the example is that this is how NOT to do it in C++. There are two better options: void f(int n, int x) { Gadget p(n); // Stack allocated // ... if (x Or, if it really has to be a pointer: void f(int n, int x) { std::unique_ptr p = new Gadget(n); // Smart pointer // ... if (x Both will be automatically freed as soon as the scope is exited.

What I was hoping you'd say :) This is fine until I want to do this, at which point C++ becomes a memory management bastard: void f(int n, int x) { Gadget g = new Gadget(n); // ... if (x

This code makes no sense. I think you do not understand C++ very well.

Re: Bjarne Stroustrup – The Essence of C++ [video]

#53

I look at Java code and it horrifies me. Java is great if your resource is memory. It turns into a horrible unsafe mess the moment your resources are not memory. //C++ RAII goodness. void foo() { conn.open(); file.open(); printer.activate(); //do stuff } //Java's lack of RAII is disturbing void foo() { try{ conn.open(); file.open(); printer.activate(); //do stuff } catch(Exception e) { } finally{ try { conn.close();…

You can write bad code in any language. No experienced Java coder would write a code like this. Java has ARM blocks for dealing with deterministic resource cleanup.

Reality is there are many Java code bases which handle resources like this. For java 6 and below this not bad code; it is how you are forced to deal with resources.

Even with the new block syntax, you have painful nesting if the operation requires several disparate resources.

Blocks are an improvement, but not the same as RAII. A block is literally converted to a try-finally by the compiler. It is the same thing with a cleaner syntax. There is no safety added to the old Java way. A programmer can forget to put his stuff in a block and leak the resource the same as he forgets to use a try-finally. The onus is on the consumer, not the library writer.

With RAII the onus is removed from the consumer. The consumer writes safe code automatically, no onus to remember any special clean up idioms.

Re: Bjarne Stroustrup – The Essence of C++ [video]

#54
post #26

If you've ever wondered what's the deal with C++ and why it's being used in 2013, you might wanna watch this. Stroustrup isn't a very flashy speaker, but he says some incredibly insightful things. C++'s C heritage makes it hard to master and also causes countless misconceptions. Even if you never want to use C++, it's worth looking into some of the unique concepts that, sadly, didn't catch on in other languages so fa…

> C++'s C heritage

Well, at this point it's more like C++'s C++ heritage.

> const correctness

It certainly exists in plenty of other languages, but in a non-broken way. C++'s const correctness model is mostly broken, by the way [1]. D's model is a bit more sane [2]. Languages like Haskell or Clojure (AFAIK) make immutability a default. This kind of functional style is a good thing for C++ developers overall, as emphasized by John Carmack [3].

[1] Once again, the C++ FQA has plenty of wisdom to share: http://yosefk.com/c++fqa/const.html [2] http://en.wikipedia.org/wiki/Const-correctness#const_and_imm... [3] http://www.altdevblogaday.com/2012/04/26/functional-programm...

> RAII didn't catch in other languages

That's because most other languages are garbage collected. (Not that RAII is a bad thing, it's just not needed.)

Re: Bjarne Stroustrup – The Essence of C++ [video]

#55

I look at Java code and it horrifies me. Java is great if your resource is memory. It turns into a horrible unsafe mess the moment your resources are not memory. //C++ RAII goodness. void foo() { conn.open(); file.open(); printer.activate(); //do stuff } //Java's lack of RAII is disturbing void foo() { try{ conn.open(); file.open(); printer.activate(); //do stuff } catch(Exception e) { } finally{ try { conn.close();…

Java 7 introduced a new language construct, called the try-with-resources statement, for automatic resource management: void foo() { try (open file or resource here) { // do stuff } // after try block, resource will close automatically } This works with non-memory resources such as files, streams, sockets, and database connections.

Pasting a response:

Blocks are an improvement, but not the same as RAII. A block is literally converted to a try-finally by the compiler. It is the same thing with a cleaner syntax. There is no safety added to the old Java way. A programmer can forget to put his stuff in a block and leak the resource the same as he forgets to use a try-finally. The onus is on the consumer, not the library writer.

With C++ RAII the onus is removed from the consumer. The consumer writes safe code automatically, no onus to remember any special clean up idioms.

Re: Bjarne Stroustrup – The Essence of C++ [video]

#56
post #26

If you've ever wondered what's the deal with C++ and why it's being used in 2013, you might wanna watch this. Stroustrup isn't a very flashy speaker, but he says some incredibly insightful things. C++'s C heritage makes it hard to master and also causes countless misconceptions. Even if you never want to use C++, it's worth looking into some of the unique concepts that, sadly, didn't catch on in other languages so fa…

There are also some things that are powerful but I'm not quite sure if I really like them. For instance, he promotes the use of handles instead of pointers. He goes through these variants: Gadget* p = new Gadget(n); // not exception safe shared_ptr p{new Gadget(n)}; //exception safe unique_ptr p{new Gadget(n)}; //exception safe and less wasteful than shared_ptr if local Gadget g{n}; //his preferred solution My proble…

> My problem with his preferred solution is that I cannot know that Gadget is really a handle to a shared Gadget and not a big fat Gadget value on the stack. The only way of knowing that is to look at the implementation or the documentation.

I'd say you do not _need_ to know. If Gadget contains tons of data, it's wiser for it to just put that on the heap, internally. Like std::vector does. As long as Gadget handles (or forbids) copying, assigment etc. (rule of three), that's fine.

If you do have a huge performance issue because you're using a class that, unwisely, puts tons of data on the stack, you can use a unique_ptr instead. Kind of an edge case in my experience though.

Re: Bjarne Stroustrup – The Essence of C++ [video]

#57
post #11

Earlier quoted context omitted.

Java: void f(int n, int x) { Reader fr = new FileReader("foo.txt"); // ... if (x A garbage collector that gives a false sense of security is much worse than no garbage collector at all.

try/finally in Java / using in C# are designed for that scenario.

They are poor solutions compared to RAII: leaky abstractions which are non-composable and error prone. Unfortunately, something like C# using is probably the best you can do in a language without clear ownership semantics like C++.

Re: Bjarne Stroustrup – The Essence of C++ [video]

#58
post #54
post #26

If you've ever wondered what's the deal with C++ and why it's being used in 2013, you might wanna watch this. Stroustrup isn't a very flashy speaker, but he says some incredibly insightful things. C++'s C heritage makes it hard to master and also causes countless misconceptions. Even if you never want to use C++, it's worth looking into some of the unique concepts that, sadly, didn't catch on in other languages so fa…

> C++'s C heritage Well, at this point it's more like C++'s C++ heritage. > const correctness It certainly exists in plenty of other languages, but in a non-broken way. C++'s const correctness model is mostly broken, by the way [1]. D's model is a bit more sane [2]. Languages like Haskell or Clojure (AFAIK) make immutability a default. This kind of functional style is a good thing for C++ developers overall, as empha…

> It certainly exists in plenty of other languages, but in a non-broken way. C++'s const correctness model is mostly broken, by the way [1]. D's model is a bit more sane [2]. Languages like Haskell or Clojure (AFAIK) make immutability a default.

What in particular is broken about const correctness in C++? That things are not const by default? I agree, they should be, but I wouldn't really call that broken. I put const wherever I can, just like Carmack. So I sort of pretend it's the default :)

I don't think it makes sense to compare const correctness in C++ to immutability in Clojure. In Clojure, you don't have objects that encapsulate internal state. const in C++ allows you to say which methods do change internal state and which don't. If you pass a const reference, the receiver can only call const methods. I just learned from you that D has this, wasn't aware of any other OOP language that has it. Not even Scala :(

> That's because most other languages are garbage collected. (Not that RAII is a bad thing, it's just not needed.)

RAII is about more than just memory, it's about any kind of resource. That includes stuff like file handles, Java's try {} finally {} is IMO a weird workaround. In C++, stream's can just close themselves when they go out of scope.

Re: Bjarne Stroustrup – The Essence of C++ [video]

#59
post #58
post #54

Earlier quoted context omitted.

> C++'s C heritage Well, at this point it's more like C++'s C++ heritage. > const correctness It certainly exists in plenty of other languages, but in a non-broken way. C++'s const correctness model is mostly broken, by the way [1]. D's model is a bit more sane [2]. Languages like Haskell or Clojure (AFAIK) make immutability a default. This kind of functional style is a good thing for C++ developers overall, as empha…

> It certainly exists in plenty of other languages, but in a non-broken way. C++'s const correctness model is mostly broken, by the way [1]. D's model is a bit more sane [2]. Languages like Haskell or Clojure (AFAIK) make immutability a default. What in particular is broken about const correctness in C++? That things are not const by default? I agree, they should be, but I wouldn't really call that broken. I put cons…

> What in particular is broken about const correctness in C++?

The lack of transitivity for one. Const pointers shouldn't be able to modify the pointed objects (that's the default in the D language). The fact that working with non-const-correct libraries is a nightmare (prepare to const_cast a lot!). There are plenty of other things that make this a real PITA to work with on sizable projects with legacy or outside code.

> RAII is about more than just memory, it's about any kind of resource.

That's true, yeah, though most of the time it's about memory (with smart pointers). But you're absolutely right on that point.

As far as I know, Common Lisp users have some kind of RAII with macros, but I'm not familiar enough to compare it to C++. Of course, D also has support for this idiom.

Re: Bjarne Stroustrup – The Essence of C++ [video]

#60
post #49

Earlier quoted context omitted.

Is the std::move call really necessary? It's a little sad if the compiler can't see that s is already an rvalue.

Once things have a name and you can take their address they are no longer an rvalue. It would require a much more sophisticated type system to do this automatically (when you pass a reference to another function, does it capture it?). It would also be non-obvious when you were moving. Think of Java style escape analysis vs C++ stack allocation (implicit vs explicit). There is one case where the compiler will do this…

The argument here is that in the body of the constructor the developer probably doesn't use s, so a trivial analysis of the function can say "oh, it doesn't matter if I destroy s, so in the one place where it is used I'll just move it". It doesn't then matter if it is obvious it happens or not, because the semantics of the program wouldn't be maintained (and honestly, I'd argue it is never quite obvious when what happens in different contexts given the large number of rules involved: you kind of just have to have some trust).
Post reply on HN