Wow, he just really really does not like C++. He is certainly an extremely knowledgeable C++ guy, obviously Swift is written in C++, but it's hard to entirely agree with his opinion on it across all fronts.
On one way we love the language, the expressive power it gives us, the type safety taken from Simula and Algol, thanks to C++'s type system.
On the other hand like Chris puts it "has its own class of problems because itʼs built on the unsafety of C".
So some of us tend to work around it, by using safer languages and only coming down to C++ for those tasks, where those better languages cannot properly fulfil them.
But as the CVE database proves, it only works if everyone on the team cares about safety, otherwise it is a lost game, only fixable by preventing everyone on the team to write C style unsafe code to start with.
Sure nowadays there are plenty of analysers to ensure code safety, but they work mostly on source code and like any tool, suffer from people really caring to use them.
It's still in early development, but there is a tool[1] that automatically converts potentially unsafe C/C++ code to be memory-safe. If the problem is C/C++ programmers that write unsafe code, rather than trying to change their practices (or even change the language they program in) maybe it's more practical to just have a robot "fix" the code.
As someone who spent over 20 years writing applications in C, anything built on C is crap and that includes C++ and Objective C.
Writing code is fun and interesting. But most software development is not writing code. It's a little bit of build management, even more testing, but mostly it's debugging. Debugging is not as fun as writing code. Every language feature that makes debugging more necessary, harder to do and more time intensive sucks. Dangling pointers are the absolute worst.
I can easily give up multiple inheritance for a more functional language that's far easier to write correct code in.
> As someone who spent over 20 years writing applications in C, anything built on C is crap and that includes C++ and Objective C.
Maybe that the problem, if you see C++ as something "built on C" then it logical that the see a lot of the same problem. C++ evolved from C to specifically address a lot of the weakness in C.
> Every language feature that makes debugging more necessary, harder to do and more time intensive sucks. Dangling pointers are the absolute worst.
language design is an exercise in compromise, and there is space for multiple compromise points on the spectrum. C++ decided (for better or for worst) to go for performance vs nice debugging experience.
> I can easily give up multiple inheritance for a more functional language that's far easier to write correct code in.
Am i the only getting tired of this kind of blanket statements ?
The problem with C++ is, that for all its added complexity and powers, most C code still is correct C++ code, especially all the unsafe pointer manipulations. And there is no real performance reason. Many static typed languages compile to code as fast as C - if not faster thanks to tighter semantics. (Other than that some C compilers are better quality because of the effort went into them due to language popularity rather than any language feature)
> most C code still is correct C++ code
Syntaxicaly yes, but with a more precise semantic and clearer stated "undefined behavior". The canonical example is the work around type punning and such.
> And there is no real performance reason. Many static typed languages compile to code as fast as C - if not faster thanks to tighter semantics.
Speed is only one part of the equation. For stuff like drivers and low level embedded development, we still needs C like unsafe memory manipulation. Rust,D,C# etc all have ways to do that.
> Many static typed languages compile to code as fast as C - if not faster thanks to tighter semantics. (Other than that some C compilers are better quality because of the effort went into them due to language popularity rather than any language feature)
With Valgrind, I would say dangling pointers are a solved problem by now. The real debugging headaches in C++ come from stuff like autogenerated constructors, overloading, template specialization, and other features that change semantics without requiring the syntax of the code that experiences the change to reflect that change. My unpopular opinion is that exceptions also fall into this class of dark features.
> With Valgrind, I would say dangling pointers are a solved problem by now.
Given the frequency with which use-after-free vulnerabilities are discovered in C++ programs, I’d say they’re not a solved problem. Valgrind is great but it doesn’t help when the only inputs that cause bad behavior are bizarre attacker-generated ones.
Only on the platforms that support Valgrind, with teams that bother to use it.
Given that Apple, Microsoft and Google keep doing presentations about such tools at their conferences, and my experience at enterprise level, I would say not so many bother to use them.
Avoiding dangling pointers requires a bit of discipline in pre-ARC Objective-C and C++, but now that we have ARC, isn't ObjC pretty much as safe as Swift? (Unless you explicitly use "assign" properties, of course.)
Objective-C's solution had its downsides, though. The classic `[firstName stringByAppendingString:lastName];` being fine when `firstName` is nil, but not if `lastName` is (though it doesn't always crash if `lastName` is nil – it's fine if `firstName is also nil!). Or how `[myObject isEqualTo:myObject]` returns false if `myObject` is nil. Or how adding a nil object to an NSArray doesn't crash (but is likely a bug!) when calling `arrayWithObjects:`, but does crash when it's an array literal.
These aren't world-ending problems, and you learn the rules easily enough, but it's like Objective-C only solved 1/2 of the problem.
Then there's the really strange corner cases, like how sending a message to nil was undefined behavior:
- when expecting a returned struct, before Apple switched to LLVM 3.0 (would vary depending on the platform's ABI, as well as the size of the struct)
- when expecting a returned floating-point value on PPC <= 10.4,
- when expecting a returned `long long` on PPC (it happened to return `(long)selector`)
For the record, I always loved how Objective-C handles this – I definitely preferred it to Java, Ruby, etc. where you're constantly checking for null or catching NPEs. But I like Swift's solution even more. I no longer have to remember about which parameters are nullable, or sanitize my inputs with `NSParameterAssert`s, etc.
No because there is the whole C part of Objective-C, including UB.
So unless there is some validation of 100% of the code writen by the team and third party libraries, it is impossible to ensure there aren't C style coding tricks being used.
Also ARC only applies to Cocoa like classes, there is no bounds checking, implicit casts are like in C, C style strings are still used in many APIs, and this are just a few examples of unsafety.