News for hackers. Stuff that matters.
Re:A Universal I/O Abstraction for C++ (2020) by pjmlp on Sunday April 18, 2021 @05:26PM (#26856546)
Nah, that place I leave for C, the number one reason we keep having memory corruption issues during the last 50 years of computer history, and having taited every language that has some level of compatibility with it.
Re:A Universal I/O Abstraction for C++ (2020) by xjay on Sunday April 18, 2021 @06:32PM (#26857132)
The late pioneer in compiler optimization--Frances Allen--agrees.

2006: "..but something else had happened--and that was back in 1973--[something] which I was very, very unhappy about--and that was the advent of C! It derailed, as far as I was concerned, the advances that I foresaw in compilers. One cannot let the user play with the addresses, and use procedures, and play with pointers--which is pointing to the data--and be able to understand how one can transform the program to run more optimally."

"There was an interesting debate at the SIGPLAN conference in that period--about the relative need for optimization. It was put on the table that it wasn't going to be needed anymore! So. Anyway. You can have your own opinion on that, but I know I have mine, beyond a doubt that it was a huge setback for--in my opinion--languages and compilers--and the ability to deliver performance--easily--to the user."

https://en.m.wikipedia.org/wiki/Frances_Allen

https://www.youtube.com/watch?v=NjoU-MjCws4&t=2450

Re:A Universal I/O Abstraction for C++ (2020) by flukus on Sunday April 18, 2021 @07:15PM (#26857460)
> One cannot let the user play with the addresses, and use procedures, and play with pointers--which is pointing to the data--and be able to understand how one can transform the program to run more optimally."

Well 50 years on we still haven't seen any of these "sufficiently smart compilers", at best they can outsmart C compilers in a few cases with things like generics, so the idea that higher level languages would be faster has been wrong for at least 5 decades. At least you can forgive them for thinking they would 50 years ago, but now it's just ignoring 50 years of reality.

Re:A Universal I/O Abstraction for C++ (2020) by oldmanhorton on Monday April 19, 2021 @09:57AM (#26862807)
Unfortunately, this assumes everyone is a master at C and that we are comparing straight line speed. In the real world, higher level languages have a much better comparison since everyone's C program has their own slow, buggy "standard" library instead of the hyper optimized ones of higher level languages. One of the major reasons why that is the case is because C, at a language design level, makes building those kinds of high level, interesting, performant, and safe APIs hard
Re:A Universal I/O Abstraction for C++ (2020) by flukus on Monday April 19, 2021 @07:03PM (#26868829)
> In the real world, higher level languages have a much better comparison since everyone's C program has their own slow, buggy "standard" library instead of the hyper optimized ones of higher level languages.

In the real world we've pissed away 30 years of hardware improvements primarily through switching to higher level languages. In the real world higher level languages are still not used we're performance counts (like games). In the real world low level languages like c and C++ are still powering our most important and fundamental projects.

Re:A Universal I/O Abstraction for C++ (2020) by pjmlp on Tuesday April 20, 2021 @02:07AM (#26871228)
In real world politics also count higher than techinical capabilities.

Source, replacing GUI and distributed applications written in C and C++ with managed languages (AOT and JIT) for the last 20 years.

Re:A Universal I/O Abstraction for C++ (2020) by pjmlp on Monday April 19, 2021 @02:28AM (#26859651)
Funny, I remember when there were books like The Zen of Assembly programming, because C compilers just generated junk code.

I also happen to remember languages like Fortran and Ada do exist.

Re:A Universal I/O Abstraction for C++ (2020) by titzer on Sunday April 18, 2021 @06:56PM (#26857309)
She's exactly right. I'm really not sure how we came to accept the worse-is-better argument that high performance required exposing machine details into the source language, and letting compiler writers just "do whatever is fastest", regardless of safety. It gave rise to today's situation where none of application writers, library writers, kernel writers, or compiler writers are quite sure what will happen if a new optimization is introduced. Will it break programs? By how much? Well, let's roll the dice! This is a direct result of allowing--no, even expecting--programmers to peer behind the curtains to see machine details that they frankly, shouldn't. It's why porting programs from one machine to another is even a thing, as opposed to just selecting a different output from a compiler, or running a different VM.

Proper abstractions define exactly what happens in every situation, and design unobservable details out. It is the basis for optimizations that fundamentally cannot observed (except side-channels, like timing and other resource usage). Proper abstractions is why we have fast processors. The ISA is a hard boundary.

Re:A Universal I/O Abstraction for C++ (2020) by linkdd on Sunday April 18, 2021 @05:30PM (#26856577)
This kind of comments are forgetting all the good that C did bring in the last 50 years of computer history.

<sarcasm>Too bad those shitty engineers in the 70s didn't think of Rust...</sarcasm>

Re:A Universal I/O Abstraction for C++ (2020) by miohtama on Sunday April 18, 2021 @06:11PM (#26856965)
They thought many ideas of it (see Lisp, Smalltalk) but computers where not powerful enough for complex compilers. Instead, the burden of ensuring correctness had to be left as the cognitive burden for the developer for decades to come.
Re:A Universal I/O Abstraction for C++ (2020) by MaxBarraclough on Sunday April 18, 2021 @08:08PM (#26857843)
> They thought many ideas of it (see Lisp, Smalltalk) but computers where not powerful enough for complex compilers.

That's probably true for borrower-checking specifically, but I don't think it accounts for all language-design breakthroughs. There were decades between the development of functional programming languages, and widespread hybrid languages which incorporated those ideas (e.g. modern Python and C#).

Re:A Universal I/O Abstraction for C++ (2020) by pjmlp on Monday April 19, 2021 @01:18AM (#26859313)
See Burroughs B5500, created in 1961 with ESPOL/NEWP, 10 years before C was even an idea.
Re:A Universal I/O Abstraction for C++ (2020) by mhh__ on Sunday April 18, 2021 @06:32PM (#26857129)
Adding slices to C would kill a lot of bugs without going all the way to rust.
Re:A Universal I/O Abstraction for C++ (2020) by jabl on Sunday April 18, 2021 @05:50PM (#26856771)
> <sarcasm>Too bad those shitty engineers in the 70s didn't think of Rust...</sarcasm>

True, Rust didn't exist back then, and yes, some (few!) features in Rust weren't invented and worked out then, like the ownership model.

OTOH the corollary to that statement isn't that C was some shining beacon of good design taking advantage of the then state of the art programming language knowledge. See e.g. https://pastebin.com/UAQaWuWG

Re:A Universal I/O Abstraction for C++ (2020) by rualca on Sunday April 18, 2021 @06:20PM (#26857035)
That pastebin leaves out the fact that C's spartan approach and extreme simplicity allowed C to become the most popular programming language in the world already in the time of K&R, a book still renowned for it's clarity and low mental baggage required to onboard onto a programming language.

The pastebin also left out that Bjarne Stroustrup developed C with classes, and the C, as a backward compatible superset of C to take advantage of C's unrivaled popularity.

We all can agree that the science and art behind programming language design progressed a lot in the four decades where we enjoyed C. However, it feels a kin to rewriting history to depict C as a subpar language that was poorly designed and had little to no redeeming qualities, when facts speak for themselves.

Re:A Universal I/O Abstraction for C++ (2020) by jabl on Monday April 19, 2021 @02:34AM (#26859681)
> However, it feels a kin to rewriting history to depict C as a subpar language that was poorly designed and had little to no redeeming qualities, when facts speak for themselves.

It was subpar compared to the state of the art then. It's redeeming quality was that it worked on the PDP-11, whereas the better languages required mainframe level resources. The tragedy isn't that C was invented, it fitted it's niche back then. The tragedy is that as HW evolved the world remained stuck with C rather than switching to better languages.

Re:A Universal I/O Abstraction for C++ (2020) by titzer on Sunday April 18, 2021 @07:02PM (#26857363)
C was not extremely simple. Lisp was extremely simple.
Re:A Universal I/O Abstraction for C++ (2020) by Koshkin on Sunday April 18, 2021 @07:53PM (#26857759)
Problem was, real world programming in Lisp was not simple.
Re:A Universal I/O Abstraction for C++ (2020) by pjmlp on Monday April 19, 2021 @02:58AM (#26859807)
Just like real world programming in C is hardly memory corruption free, and only around 10% of survey answers keep asserting to use any kind of memory assurance tooling.
Re:A Universal I/O Abstraction for C++ (2020) by jabl on Monday April 19, 2021 @03:30AM (#26859974)
The other 90% are the better than average programmers who don't need such training wheels. /s
Re:A Universal I/O Abstraction for C++ (2020) by Koshkin on Sunday April 18, 2021 @07:59PM (#26857792)
Actually, computer science in general and the theory of programming languages in particular were already very advanced back in the 60s. It’s just people thought little of languages that would have needed gigabytes of memory (or days of run time) for the compiler to do its job.
Re:A Universal I/O Abstraction for C++ (2020) by jabl on Monday April 19, 2021 @02:27AM (#26859643)
That's exactly the point the pamphlet I linked to makes. C was far from the state of the art when it was invented, it's only major redeeming quality was that it worked on the shit low-end computers that were available to the inventors back then.

The tragedy wasn't that C was invented, it was fit for purpose then. The tragedy was that as HW evolved beyond the PDP-11 level, unix programming remained stuck at C.

Re:A Universal I/O Abstraction for C++ (2020) by pjmlp on Monday April 19, 2021 @01:16AM (#26859303)
Like the Go designers ignored generics, they ignored the safer systems programming languages developed as ALGOL and PL/I variants during the 60s.

https://www.bell-labs.com/usr/dmr/www/chist.html

Re:A Universal I/O Abstraction for C++ (2020) by titzer on Sunday April 18, 2021 @07:01PM (#26857356)
No one can seriously argue that C's language design was inherently advantageous over, say, Pascal. If Lisp, ML, Simula, Algol, or Ada received the amount of optimization and porting investment that C did, history would be very different.

C succeeded because a.) Unix, and b.) there were a zillion platforms with a zillion different compilers that could process something like C. They all did weird things and you couldn't actually write portable code for decades, but you could kind of fake it.

Re:A Universal I/O Abstraction for C++ (2020) by refenestrator on Sunday April 18, 2021 @11:52PM (#26858969)
That portability to a zillion platforms was part of the language design, though. 'Portable assembler' and all that.
Re:A Universal I/O Abstraction for C++ (2020) by pjmlp on Monday April 19, 2021 @01:20AM (#26859324)
All high level languages are portable, and many already were before C came to be.

Just marketing speak.

Re:A Universal I/O Abstraction for C++ (2020) by refenestrator on Monday April 19, 2021 @09:01AM (#26862259)
Sure, with more or less effort. C's semantics seem very easy to port, with very little abstraction over the commonalities that all (most?) assemblies share: computer as a giant array with a CPU and registers.

There's a gaping hole in the abstraction when it comes to word size, but that's about it, and it's obvious to diagnose at least.

Compared to the list of languages above with their more advanced features, it's super easy to port a C compiler and start compiling code. Worse is better.

Re:A Universal I/O Abstraction for C++ (2020) by pjmlp on Monday April 19, 2021 @09:04AM (#26862284)
So easy that to actually make C portable, UNIX had to be made into a C standard library via POSIX, otherwise portable C code is basically just logic and data structures.
Re:A Universal I/O Abstraction for C++ (2020) by refenestrator on Monday April 19, 2021 @09:11AM (#26862353)
Sure, but the flipside of that is that UNIX itself is fairly easy to port to a new CPU, due to being mostly written in C.

So port your compiler, figure out a syscall interface on your CPU, patch it into unix/libc and compile them, and.. it's not like that's a small amount of work but it's way easier than bootstrapping any other environment from scratch on a new architecture.

There's surely some amount of historical accident here as well, but no other language/OS combo ran on like 12 different architectures in the 80s.

Re:A Universal I/O Abstraction for C++ (2020) by pjmlp on Monday April 19, 2021 @11:04AM (#26863499)
Because no other timesharing OS was available in free beer source code for others to port it, it had nothing to do with C.
Re:A Universal I/O Abstraction for C++ (2020) by agumonkey on Sunday April 18, 2021 @07:19PM (#26857486)
Actually I'd bet a dollar or two that linear threading of resources existed even before C, it just wasn't neither a common practice nor a theoretical framework at the time.
Re:A Universal I/O Abstraction for C++ (2020) by Koshkin on Sunday April 18, 2021 @07:46PM (#26857715)
Have been programming in C (and then C++), like, forever. Hardly any memory corruption issues. Yes, you have to be a little more disciplined and pay attention to things. Being distracted certainly does not help.
Re:A Universal I/O Abstraction for C++ (2020) by pjmlp on Monday April 19, 2021 @01:21AM (#26859334)
If powerhouses like ARM, Apple, Google, Microsoft and even Linux kernel admit not being able to, now even pushing for hardware memory tagging as the only remaining way to fix C and its influence on C++/Objective-C, you are indeed a top expert.
Re:A Universal I/O Abstraction for C++ (2020) by MaxBarraclough on Sunday April 18, 2021 @08:05PM (#26857823)
A significant fraction of major security vulnerabilities in C/C++ codebases relate to memory-management bugs.
Re:A Universal I/O Abstraction for C++ (2020) by secondcoming on Monday April 19, 2021 @03:59AM (#26860132)
How old is the code though? It's actually really hard to get modern C++ wrong
Re:A Universal I/O Abstraction for C++ (2020) by MaxBarraclough on Monday April 19, 2021 @06:57AM (#26861261)
> It's actually really hard to get modern C++ wrong

That's not true. The language is full of footguns, from its basic expressions (signed overflow, integer division-by-zero, and read-before-write are all undefined behaviour) up to concurrency (data-races are undefined behaviour) and everything in between (unsafe arrays, unsafe memory management, alignment, the list goes on). The high-level constructs in modern C++ help, but you're never further than one misstep from undefined behaviour.

Even high-profile codebases by highly skilled teams using all the modern tools, still run into trouble. Even Chromium has security issues arising from the dangers of C++. The push for Rust is out of pragmatism, not trend-chasing or theoretical purity.

Of course, C codebases like the Linux kernel also continue to have these issues.

Re:A Universal I/O Abstraction for C++ (2020) by pjmlp on Monday April 19, 2021 @06:31AM (#26861105)
Re:A Universal I/O Abstraction for C++ (2020) by MaxBarraclough on Monday April 19, 2021 @06:59AM (#26861273)
I'm less optimistic. Even major C++ projects that do everything right, still have issues that would have been prevented had they used a safe language. My go-to example is Chromium.
Re:A Universal I/O Abstraction for C++ (2020) by v8dev123 on Monday April 19, 2021 @12:55PM (#26864995)
Rust doesn't prevents logical bugs. Chromium had plenty of those. Most are capable of RCE. They were more dangerous than memory ones because they bypass sandbox in one-click.

As for Windows, The Russians exploited a logical bug in kernel for privilege escalation.

Rust also doesn't prevents overflows, DoS, UaF, OOB.

For example, see CVE-2018-1000657

Another dangerous thing about Rust is Crates. Crates doesn't audit packages for malware and you will face far worse than NPM like situation in future.

Re:A Universal I/O Abstraction for C++ (2020) by MaxBarraclough on Monday April 19, 2021 @03:38PM (#26867040)
> Rust doesn't prevents logical bugs. Chromium had plenty of those.

Right, but that's not the goalpost we're discussing. We're talking about languages that can guarantee safety - the absence of undefined behaviour - not languages that can fully guarantee correctness (e.g. SPARK).

> Rust also doesn't prevents overflows, DoS, UaF, OOB.

In Rust, integer overflow does not cause undefined behaviour. In Safe Rust, undefined behaviour cannot arise from buffer overflows, use-after-free, or out-of-bounds array access. Safe Rust precludes all undefined behaviour, after all. Unsafe Rust may be 'more safe' than C++ in degree, but not in category: it's an unsafe language, as you say.

> Another dangerous thing about Rust is Crates.

Again, sure.

Re:A Universal I/O Abstraction for C++ (2020) by v8dev123 on Monday April 19, 2021 @04:11PM (#26867420)
> integer overflow does not cause undefined behavior

Source please?

I ask this since Rust doesn't have a formal specification and I can't keep up with it's inner changes.

It did cause undefined behavior in my case but that was 4 years ago.

Re:A Universal I/O Abstraction for C++ (2020) by steveklabnik on Monday April 19, 2021 @04:52PM (#26867852)
It wasn’t undefined behavior four years ago either. RFC 560, from 2014, defines this behavior. As far as I can recall, this was mostly a codification of what was already in place; I’m pretty sure it was never UB.
Re:A Universal I/O Abstraction for C++ (2020) by MaxBarraclough on Monday April 19, 2021 @05:06PM (#26867994)
Here's a source. [0] In release builds, overflow results in two's complement wrapping. In debug builds, it results in a panic at runtime. It never results in undefined behaviour.

Safe Rust really is a safe language. That's really what's remarkable about Rust: it has high ambitions for safety and usability and performance, and it's succeeding in achieving them.

(I hear there are some who want to dilute the safety guarantees of Safe Rust. I'm optimistic that they will continue to be ignored.)

[0] https://doc.rust-lang.org/book/ch03-02-data-types.html#integ...

Re:A Universal I/O Abstraction for C++ (2020) by v8dev123 on Monday April 19, 2021 @05:30PM (#26868170)
> Relying on integer overflow’s wrapping behavior is considered an error

Your doc also says this.

> I hear there are some who want to dilute the safety guarantees of Safe Rust

Unfortunately, I don't use Rust at work. I can't talk about it anymore, either. I can't use an informal reference to reason about its actual behavior. At the end of the day, C++ puts food on the table. I try to improve C++ as much as possible, knowing that it is an imperfect language. C++ is heading into safe direction, and I'm sure C++26 will be able to provide more features to write code safely.

Rust seriously need to add Function Overloading, Generics.

Re:A Universal I/O Abstraction for C++ (2020) by MaxBarraclough on Tuesday April 20, 2021 @05:47AM (#26872593)
> I can't use an informal reference to reason about its actual behavior.

I don't follow here. You can do that. There's a more formal reference too though. [0]

> Relying on integer overflow’s wrapping behavior is considered an error

Good point, I'd missed that. So, Rust strongly discourages relying on the wrapping behaviour of release builds. It seems to take the opposite approach that Java uses.

In Java, you get wrapping arithmetic 'by default' (i.e. when using the arithmetic operators), and there are special functions that give throw-on-overflow behaviour (which almost no one uses). [1] In Rust, the arithmetic operators handle overflow either by wrapping or by panic, depending on build configuration, and if you deliberately want to overflow, there are special functions for that (i32::wrapping_add) which behave identically on Debug and Release builds.

I believe Ada does something similar.

> At the end of the day, C++ puts food on the table. I try to improve C++ as much as possible, knowing that it is an imperfect language.

Sure, I use C++ too. I really only know about Rust from a distance, I'm not a Rust programmer. C++ still has considerable advantages: excellent first-class support on all major platforms, a wealth of libraries available, mature tooling (static analysis, dynamic analysis, top-notch IDEs). Of course, some major software frameworks are natively C++, so you're strongly encouraged to stick with C++ (Qt, Direct3D).

> C++ is heading into safe direction, and I'm sure C++26 will be able to provide more features to write code safely.

The C-style footguns will probably still be there in 20 years. Yes, they've given us std::vector and std::array which allow us to manage arrays more safely than raw C arrays, but read-before-write is still undefined behaviour, dereferencing null is still undefined behaviour, divide-by-zero is still undefined behaviour. They gladly add more functionality to the standard library, but they're very reluctant to tweak the core of the language. At least we have two's complement guaranteed by the C++ standard now.

> Rust seriously need to add Function Overloading, Generics.

I wasn't aware Rust lacked generics. That sounds frustrating.

I have mixed feelings on function overloading. It makes it harder to reason about what function is being called.

[0] https://doc.rust-lang.org/reference/behavior-not-considered-...

[1] https://docs.oracle.com/en/java/javase/16/docs/api/java.base...

Re:A Universal I/O Abstraction for C++ (2020) by v8dev123 on Tuesday April 20, 2021 @09:42AM (#26874521)
> read-before-write is still undefined behaviour, dereferencing null is still undefined behaviour, divide-by-zero

You rarely do these in Modern C++.

It's your responsibility to check the input of program before doing anything with it.

Structured Exception Handling aka SEH Exceptions can catch things like divide-by-zero, read-before-write, dereferencing null

> The C-style footguns will probably still be there in 20 years.

It's your job to know these footguns. Actually, it will take 2-3 months for a new programmer to separate C++ and C and understand what Modern C++ actually about.

> I have mixed feelings on function overloading. It makes it harder to reason about what function is being called.

It doesn't because overloading depends on the arguments not on the function names

Without overloading, things become ugly.

Re:A Universal I/O Abstraction for C++ (2020) by MaxBarraclough on Tuesday April 20, 2021 @12:44PM (#26877105)
> You rarely do these in Modern C++.

As I said before, one way or another, undefined behaviour is still a major problem in C++ codebases. This isn't really up for debate. pjmlp provided a good link on this. Most of Chromium's serious security bugs are due to memory safety issues. [0]

> It's your responsibility to check the input of program before doing anything with it.

C++ makes it the programmer's responsibility to avoid undefined behaviour. Programmers are not capable of doing this reliably. We're now at the point that it's no longer credible to argue otherwise. Even after all these decades it's still a problem for C++.

> Structured Exception Handling aka SEH Exceptions can catch things like divide-by-zero, read-before-write, dereferencing null

Sure, and with GCC/Clang, there are equivalent flags to enable trap-on-error for these errors. They're rarely used in production though, so we still face the consequences of undefined behaviour.

> It's your job to know these footguns.

Again, we've seen that C and C++ programmers simply are not capable of avoiding undefined behaviour. Even Google is unable to keep UB out of their prized Chromium codebase, despite their considerable investment.

> It doesn't because overloading depends on the arguments not on the function names

That's the definition of overloading, not a refutation of my point.

In a language like C with no overloading, the function identifier is enough to uniquely identify the function. You don't need to check if there are overloads, the identifier is enough. If you introduce overloading, that property no longer holds. You might work under the mistaken impression there are no other overloads of a function, or it might be non-trivial to determine the types being passed, especially in the presence of type-inference.

It's resolved at compile time, rather than at runtime, but my point stands.

> Without overloading, things become ugly.

It's a tradeoff.

[0] https://news.ycombinator.com/item?id=26862330

Re:A Universal I/O Abstraction for C++ (2020) by v8dev123 on Tuesday April 20, 2021 @03:51PM (#26880513)
The thing with memory bugs is that you need another bug for Sandbox to fully exploit the browser.

Here is a real world logical exploit that knock sandbox and Rust won't prevent this stuff,

https://bugs.chromium.org/p/chromium/issues/detail?id=386988

Re:A Universal I/O Abstraction for C++ (2020) by MaxBarraclough on Tuesday April 20, 2021 @06:10PM (#26882512)
> The thing with memory bugs is that you need another bug for Sandbox to fully exploit the browser.

The quote was Around 70% of our high severity security bugs are memory unsafety problems. Doesn't sound like sandboxing is effective there.

> Here is a real world logical exploit that knock sandbox and Rust won't prevent this stuff,

I'm not sure I see your point here. No one is arguing that Safe Rust makes all logic bugs go away. It's not a formal methods framework, it's a safe programming language. If Chromium had been written in Safe Rust (assuming that's practical), presumably at least 70% of its high-severity security bugs would have been avoided.

You're right that they still wouldn't have perfection. The only shot at perfect security is through formal methods, following SeL4, but as things stand, formal methods cannot scale to a problem as large as a modern web browser. Sadly, even TLS is beyond what we can implement with formal methods.

Re:A Universal I/O Abstraction for C++ (2020) by v8dev123 on Tuesday April 20, 2021 @07:18PM (#26883286)
> The quote was Around 70% of our high severity security bugs are memory unsafety problems.

This quote simply means there are 70% high severity security bugs and it doesn't implies anything about sandbox.

You can have a use-after-free exploit but it's worthless without a sandbox escape.

Sandboxing is very effective at memory bugs but certainly bad at logical bugs.

Re:A Universal I/O Abstraction for C++ (2020) by pjmlp on Monday April 19, 2021 @09:09AM (#26862330)
Agreed, I keep reaching for C++, because of the dependency many ecosystems have.

Chromium is a good example actually, I bet they would rather follow the "Custom C++ libraries" and "Hardware mitigations" than the Firefox approach.

https://www.chromium.org/Home/chromium-security/memory-safet...

Apple did something similar recently, their iBoot firmware uses a custom safe C dialect.

Re:A Universal I/O Abstraction for C++ (2020) by MaxBarraclough on Tuesday April 20, 2021 @07:09AM (#26873076)
Thanks, I'd not seen that page before.

> The Chromium project finds that around 70% of our serious security bugs are memory safety problems.

I'll point to this next time this topic crops up.