News White House urges developers to avoid C and C++, use 'memory-safe' programming languages

Page 3 - Seeking answers? Join the Tom's Hardware community: where nearly two million members share solutions and discuss the latest tech.
Status
Not open for further replies.
I note modern C++ is quite memory safe, when you avoid the legacy C baggage. And for most embedded systems (where system utilization is often known during design) you can often avoid using dynamically allocating memory which makes 99% of all memory concerns just "go away".

Regardless, the reason C and C++ remain in such use is because no other languages give the performance and flexibility.
 
I note modern C++ is quite memory safe, when you avoid the legacy C baggage.
Memory safety is more than avoiding malloc/free.

You need to limit yourself to a strict subset of language + library features in order to achieve most traits of a memory-safe language, but it doesn't get you 100%, and you'd need external tooling to enforce you don't go beyond the subset constraints.

Regardless, the reason C and C++ remain in such use is because no other languages give the performance and flexibility.
Rust seems to be a good fit for most cases where C/C++ **make sense**. And for really constrained systems (e.g. 16bit microcontrollers), we'd probably be better off with handwritten assembly, anyway 😉
 
I note modern C++ is quite memory safe, when you avoid the legacy C baggage. And for most embedded systems (where system utilization is often known during design) you can often avoid using dynamically allocating memory which makes 99% of all memory concerns just "go away".

Regardless, the reason C and C++ remain in such use is because no other languages give the performance and flexibility.
No, performance isn't among top reasons for sticking with C/C++. In my experience, if you suggest to use a different programming language when submitting your patches to an open-source project (other than the language(s) the project is using as the main programming language(s)), one or more of the following is very likely to happen:
  • Your proposal will be disregarded and your patches won't be accepted into the project
  • The open-source project maintainers will think that you are just joking and will take your proposal lightly
  • The maintainers will think that a main reason for not using their language is that you lack experience
  • Members of the project will start to theorize about the possibility of admitting a different language into the project, but as months of time pass by it becomes clear that in practice nothing will actually happen in that direction
 
All of you saying C/C++ can be “memory safe” if you just write good code sound like people who have only ever been on the building side of software and never the attacking side of things. Everyone tries to build memory safe and secure code. The applications I and others have successfully exploited for academic purposes with buffer and stack overflows were not written to be intentionally vulnerable! This kind of hubris is exactly why the government is recommending memory safe languages.

The developers that wrote the code were intelligent people who knew what they were doing. Most of the vulnerabilities come from using standard library functions that have undiscovered bugs or simply from call stack complexity that a human can’t completely grok.

You won’t ever be a good enough programmer to prevent zero day exploits. Just use Rust unless you’re maintaining an existing C/C++ project.
 
Oh, delicious irony!

The forum just threw an error at me, in the form of a banner at the top of the window. Upon refreshing the page, I saw only:
"An unexpected database error occurred. Please try again later. "​

Nice.
Programmers that believe a user wants to know whether the error was 'expected' or not are the likely targets of this White House directive...
 
Alternatively, you could just hire developers that are aware of and care about memory utilization. I'm aware those skills are very expensive and hard to find. They do exist in older workers.

The market has been flooded with developers who have degrees or certifications with only a single semester of Java programming. As someone who went through an intense technical program where algorithm designs, run times, memory optimizations, sequencing, threading, and other important things were taught, it pains me to encounter people who exclusively rely on libraries/frameworks and think the compiler will fix everything for them.
Sadly those technical programs, like the one you went through, are quite rare, time consuming and expensive.

In company traning would help a lot of they bothered at all to do it.
 
No, performance isn't among top reasons for sticking with C/C++. In my experience, if you suggest to use a different programming language when submitting your patches to an open-source project (other than the language(s) the project is using as the main programming language(s)), one or more of the following is very likely to happen:
  • Your proposal will be disregarded and your patches won't be accepted into the project
  • The open-source project maintainers will think that you are just joking and will take your proposal lightly
  • The maintainers will think that a main reason for not using their language is that you lack experience
  • Members of the project will start to theorize about the possibility of admitting a different language into the project, but as months of time pass by it becomes clear that in practice nothing will actually happen in that direction
You mean to say that if you post your ADA patches to a C# project you are not taken 100% seriously? Somehow I am not surprised.
 
Alternatively, you could just hire developers that are aware of and care about memory utilization. I'm aware those skills are very expensive and hard to find. They do exist in older workers.

The market has been flooded with developers who have degrees or certifications with only a single semester of Java programming. As someone who went through an intense technical program where algorithm designs, run times, memory optimizations, sequencing, threading, and other important things were taught, it pains me to encounter people who exclusively rely on libraries/frameworks and think the compiler will fix everything for them.
This is the *correct* answer. The root problem is the rank and file simply do not know any better. And most workplaces don't have any mentorship programs, let alone any developers good enough to point out mistakes and and teach junior developers.
 
This is great, but when I try to write a desktop app using rust, I run into there is no stable, mature gui library. So I have to use something like gtk-rs, and it seems like a kludgey mess wrapping an unsafe c library, so how does this help? It seems to me the future is still a ways off.
 
  • Like
Reactions: vijosef
C's not going away any time soon: C23 is the informal name for ISO/IEC 9899:2024, the next standard for the C programming language, which will replace C17 (standard ISO/IEC 9899:2018).
C had a good 55-year run, but I think the writing is on the wall. Many of the more serious C stalwarts are starting to embrace Rust. There are apparently few contexts Rust can't scale down to fit, including microcontrollers.

C++ can be used in a mostly memory-safe way, but it requires adherence to good style and the potential for mistakes still exists. Along with its huge learning curve, that makes C++ more difficulty to defend. I might not even bother trying to justify using it for a new project
 
  • Like
Reactions: palladin9479
C's not going away any time soon: C23 is the informal name for ISO/IEC 9899:2024, the next standard for the C programming language, which will replace C17 (standard ISO/IEC 9899:2018).
Oh, I'm well aware of the C standard committee's activities. I actually think C++ should be evolving at a slower pace, similar to C.

I liked C99 and some of the stuff in C11 and C17 were long overdue, in my opinion. However, far from groundbreaking, they were largely consolidation efforts over things available as nonstandard extensions of certain compilers (mostly GCC, I think) and 3rd party libraries, plus some quality-of-life enhancements. It's not as if C is suddenly going to get lambdas or templates - nothing that would fundamentally change the way C is written or used.
 
This is great, but when I try to write a desktop app using rust, I run into there is no stable, mature gui library. So I have to use something like gtk-rs, and it seems like a kludgey mess wrapping an unsafe c library, so how does this help? It seems to me the future is still a ways off.
Rust probably isn't the best fit for desktop applications – but there's other safer-than-C/C++ languages to choose from.

I still haven't found a cross-platform UI toolkit I like, everything seems to be way too clunky and/or not have a full native feel. There's a reason garbage like Electron is spreading...
 
  • Like
Reactions: bit_user
Rust is probably the best bet for low-level code. For applications/services/whatever higher-level code there's several choices – where memory safety is just one parameter, performance characteristics and ecosystem quality are other balancing factors. But we really ought to stop doing any new development work in C/C++.
You can't replace something with nothing. Other than Rust, for lower-level code, I'm not sure what's an obvious successor to C++. It seems like there needs to be some industry consensus on a higher-level successor. I like Python, but it's almost too high-level.

C is the lowest common denominator for glueing different languages together).
C++ has pretty good interoperability with Python, from what I've seen. You can do it with C, but it's a lot more work.
 
In my experience, if you suggest to use a different programming language when submitting your patches to an open-source project (other than the language(s) the project is using as the main programming language(s)), one or more of the following is very likely to happen:
  • Your proposal will be disregarded and your patches won't be accepted into the project
  • The open-source project maintainers will think that you are just joking and will take your proposal lightly
  • The maintainers will think that a main reason for not using their language is that you lack experience
  • Members of the project will start to theorize about the possibility of admitting a different language into the project, but as months of time pass by it becomes clear that in practice nothing will actually happen in that direction
As I mentioned, the Linux kernel eventually started to embrace Rust. It wasn't an easy process, and certainly not something driven by patches being submitted out-of-the-blue. These things need a lot of discussion and some degree of buy-in from the core project stake-holders, before patches start flowing.
 
  • Like
Reactions: snemarch
C had a good 55-year run, but I think the writing is on the wall. Many of the more serious C stalwarts are starting to embrace Rust. There are apparently few contexts Rust can't scale down to fit, including microcontrollers.

C++ can be used in a mostly memory-safe way, but it requires adherence to good style and the potential for mistakes still exists. Along with its huge learning curve, that makes C++ more difficulty to defend. I might not even bother trying to justify using it for a new project.
I've always thought that Rust is more of a replacement for C++ than for C, even though it effectively compiles to C.

C++ is supposed to be a more "generic" (in terms of widely-"supporting" different paradigms) expansion of C, but has so many hidden behaviors and inconsistencies in its design and implementation rules that make it unsuitable for low-level systems. Rust fits the bill w/o the nonsensicality of C++. (and amusingly, has better compatibility w/ C than C++)

However, Rust isn't primarily tailored towards strictly straightforward imperative programming, which is the use-case that C dominates.

IMO, the "true" C replacement will be Zig, whenever it develops enough, at least...
 
Last edited:
You mean to say that if you post your ADA patches to a C# project you are not taken 100% seriously? Somehow I am not surprised.
I think it depends on whether the norm should be polyglot programming or monoglot programming. From viewpoint of the latter (monoglot), posting ADA patches to a C# project is very unusual. From the competing viewpoint (polyglot): C# runs on CLR (Common Language Runtime, a virtual machine) thus if there exists an ADA compiler which compiles to CLR then the idea of posting ADA patches to a C# project isn't that far-fetched.
 
You can't replace something with nothing. Other than Rust, for lower-level code, I'm not sure what's an obvious successor to C++. It seems like there needs to be some industry consensus on a higher-level successor. I like Python, but it's almost too high-level.
I don't think there's a one-size-fits-all replacement for higher-level stuff. Python has a bunch of good stuff, but overall I'm not a fan; subjective stuff like syntax, standard library design and it being a dynamic language... and it also doesn't perform very well (you'll basically be calling native, usually C, code whenever you need performance), and it wasn't designed for multithreading. Even Java and C# are able to do relatively high-performance stuff without depending on native code.

But hey, I'm not sure we need *one* language that's able to fill all possible roles. I've used a fair amount of programming languages, and I'm leaning towards a bit of specialization being a good thing. But there's pros and cons – especially if you mix several languages in one project.

C++ has pretty good interoperability with Python, from what I've seen. You can do it with C, but it's a lot more work.
Most FFI stuff I've seen in various languages have used C interfaces for lots of reasons (ABI, name mangling, it being easier to write whatever-language-idiomatic wrappers, etc).
 
  • Like
Reactions: Order 66
But hey, I'm not sure we need *one* language that's able to fill all possible roles. I've used a fair amount of programming languages, and I'm leaning towards a bit of specialization being a good thing. But there's pros and cons – especially if you mix several languages in one project.
You won't ever have just one language for all roles; C if you need low-level HW access and maximum performance, C++ for performance-sensitive GUI applications, and some higher level language if performance is not a major concern.

The problem is that once languages start chasing the performance of C, they start running into all the same problems (mainly that performance through working directly on memory addresses is fundamentally unsafe in at least some circumstances).

I also again note that, speaking as someone who's worked on embedded systems, that I've seen *plenty* of "memory safe" languages break in comical ways because they are designed wrong (usually in response to the restrictions the language puts on the developer). Perfect example: I worked on an Ada program (not developed by myself) that had a memory leak despite the fact Ada is quite resistant to that behavior.
 
  • Like
Reactions: palladin9479
You won't ever have just one language for all roles; C if you need low-level HW access and maximum performance, C++ for performance-sensitive GUI applications, and some higher level language if performance is not a major concern.

The problem is that once languages start chasing the performance of C, they start running into all the same problems (mainly that performance through working directly on memory addresses is fundamentally unsafe in at least some circumstances).
I don't believe we really need C/C++ for those roles anymore, though – and they both lack safety features I'd like even when dealing with embedded code. (I think it's fair to set a reasonable minimum for hardware moving forward – if you still need to do new development for 8/16bit microcontrollers, there probably aren't good modern alternatives to C/C++).

I also again note that, speaking as someone who's worked on embedded systems, that I've seen *plenty* of "memory safe" languages break in comical ways because they are designed wrong (usually in response to the restrictions the language puts on the developer). Perfect example: I worked on an Ada program (not developed by myself) that had a memory leak despite the fact Ada is quite resistant to that behavior.
You can screw up in any language that's practical to work with, we'll probably need formally proved logic to approach full safety... and that's not really feasible 😅. But memory safety is about more than just memory leaks, and we need to set the bar (a fair bit) higher than C/C++. The figures being thrown around vary a bit, but being able to avoid a whole *class* of errors probably responsible for 70% of exploitable bugs, without too much performance overhead? Yes, please.
 
  • Like
Reactions: Order 66
MCSE - Must Consult Someone Experieenced - the influx of clueless consultants.
Sadly, even companies that do have experienced engineers tend to surround 1 experienced engineer with 10 low quality resources from lowest bidder in a 12 hour different timezone. This makes it very difficult for the 1 experienced engineer to be able to police the entire product.
 
  • Like
Reactions: palladin9479
You won't ever have just one language for all roles; C if you need low-level HW access and maximum performance, ...

The problem is that once languages start chasing the performance of C, they start running into all the same problems (mainly that performance through working directly on memory addresses is fundamentally unsafe in at least some circumstances).
...and...
The figures being thrown around vary a bit, but being able to avoid a whole *class* of errors probably responsible for 70% of exploitable bugs, without too much performance overhead? Yes, please.
At the risk of being "one of those annoying Rust people" *, I'm concerned that you guys seem to be dismissing its performance potential, out of hand. So, I found a couple quick investigations into the matter.

Here's data from an article dated Nov. 2020:

1*LBw1M8vF9NZImM7o5mHY5A.png

Source: https://levelup.gitconnected.com/wh...ts-find-out-who-is-the-usain-bolt-87495c774c8
Almost looks too good to be true! Admittedly, I have not checked the C code for any obvious performance gotchas.

Here's a more recent experiment (Dec. 2023), where Rust seemed to have a bit more trouble:

compileropt_levelruntimeratio vs. best not parallel
rustrelease parallel unsafe0.410.27
gcc-O31.541.0
rustrelease v2 unsafe1.561.01
rustrelease v3 safe2.21.43
clang-O32.271.47
clang-O12.31.49
go2.341.52
(some rows omitted, for brevity)

Source: https://users.rust-lang.org/t/rust-vs-c-vs-go-runtime-speed-comparison/104107/30
The rows starting with gcc and clang are compiling the C version. Obviously, the rust compiler is compiling the Rust version and the go compiler is compiling the Go version.

Taking only 43% longer (or running 70% as fast) is certainly in the same ballpark as C! I'm not really counting the "unsafe" version, since I don't know how much safety it still retains vs. plain C.

Here's an explanation of Rust's performance characteristics, that I must admit I've barely skimmed so far.

Finally, here's a free, online book about using the Rust Programming Language on "Bare Metal" embedded systems, such as Microcontrollers. Granted, they seem to focus on 32-bit microcontrollers. I don't know if anyone is using it on 16-bit or smaller.

* FWIW, I'm not deeply familiar with Rust, myself, but have been meaning to look into it more. This little investigation was as much for my own edification as that of anyone else.
 
At the risk of being "one of those annoying Rust people" *, I'm concerned that you guys seem to be dismissing its performance potential, out of hand. So, I found a couple quick investigations into the matter.
Just to clarify: my stance is that in general it's acceptable to lose a (small!) amount of performance to eliminate classes of bugs and avoid undefined behavior, I wasn't trying to claim that Rust carries this penalty 👍

I wouldn't pick sorting algorithm benchmarks as a major evaluation point (unless the results are terribad) – sorting algorithms tend to not exercise a whole lot of language features, so you *should* see speeds that are comparable to other compiled languages, especially since several language use the LLVM infrastructure.

It's probably better to look at something like the Debian "benchmark game" – but that should also be taken with a grain of salt. Are we interested in overall performance of language-idiomatic code that you can expect to normally see in the wild, or heavily optimized implementations? E.g. somebody I know did a software-rendered Marching Cubes implementation in Java back in... early 2000s? that ran smoothly, but that definitely wasn't your standard run-of-the-mill Java code 😉

One of Rust's biggest features is how it deals with lifetime/ownership tracking, so that would be of particular interest in benchmarks. Not just for obivous cases like heap allocations, but also how it might affect arguments/return-values for stack data, handing over ownership in parallelized code, synchronization and such.

(My impression is that it does so pretty darn well, btw.)
 
...and...

At the risk of being "one of those annoying Rust people" *, I'm concerned that you guys seem to be dismissing its performance potential, out of hand. So, I found a couple quick investigations into the matter.

Here's data from an article dated Nov. 2020:
1*LBw1M8vF9NZImM7o5mHY5A.png
Almost looks too good to be true! Admittedly, I have not checked the C code for any obvious performance gotchas.

Here's a more recent experiment (Dec. 2023), where Rust seemed to have a bit more trouble:
compileropt_levelruntimeratio vs. best not parallel
rustrelease parallel unsafe0.410.27
gcc-O31.541.0
rustrelease v2 unsafe1.561.01
rustrelease v3 safe2.21.43
clang-O32.271.47
clang-O12.31.49
go2.341.52

(some rows omitted, for brevity)​
The rows starting with gcc and clang are compiling the C version. Obviously, the rust compiler is compiling the Rust version and the go compiler is compiling the Go version.

Taking only 43% longer (or running 70% as fast) is certainly in the same ballpark as C! I'm not really counting the "unsafe" version, since I don't know how much safety it still retains vs. plain C.

Here's an explanation of Rust's performance characteristics, that I must admit I've barely skimmed so far.

Finally, here's a free, online book about using the Rust Programming Language on "Bare Metal" embedded systems, such as Microcontrollers. Granted, they seem to focus on 32-bit microcontrollers. I don't know if anyone is using it on 16-bit or smaller.

* FWIW, I'm not deeply familiar with Rust, myself, but have been meaning to look into it more. This little investigation was as much for my own edification as that of anyone else.
Oh boy, are we *Seriously* going to compare sorting performance as a metric now? I wasn't aware the vast majority of code execution was doing sorting algorithms.

Also, as you yourself admitted: In *practical* workloads, Rust is about 30% slower. Which is, again, why C reigns supreme at the HW/Driver layer. But hey, lets make a Rust NVIDIA driver; I'm sure nobody here will mind a 30% performance loss in games; it's not like everyone here spends a grand plus every year for smaller performance improvements. [sarcasm heavily implied]
 
Oh boy, are we *Seriously* going to compare sorting performance as a metric now? I wasn't aware the vast majority of code execution was doing sorting algorithms.

Also, as you yourself admitted: In *practical* workloads, Rust is about 30% slower. Which is, again, why C reigns supreme at the HW/Driver layer. But hey, lets make a Rust NVIDIA driver; I'm sure nobody here will mind a 30% performance loss in games; it's not like everyone here spends a grand plus every year for smaller performance improvements. [sarcasm heavily implied]
Are games and gaming drivers targets for exploits? 30% is not an acceptable loss, no. But what is the gain supposed to be?
 
I don't believe we really need C/C++ for those roles anymore, though – and they both lack safety features I'd like even when dealing with embedded code. (I think it's fair to set a reasonable minimum for hardware moving forward – if you still need to do new development for 8/16bit microcontrollers, there probably aren't good modern alternatives to C/C++).
There aren't alternatives period; you live and die by your Board Support Package, and it's basically impossible to get anything other then C or Ada (and the latter is usually by request to the vendor nowadays).
You can screw up in any language that's practical to work with, we'll probably need formally proved logic to approach full safety... and that's not really feasible 😅. But memory safety is about more than just memory leaks, and we need to set the bar (a fair bit) higher than C/C++. The figures being thrown around vary a bit, but being able to avoid a whole *class* of errors probably responsible for 70% of exploitable bugs, without too much performance overhead? Yes, please.
The majority of those bugs are addressed by using modern structures that directly address the underlying problems of the base language/libraries. Smart Pointers (C++14) basically solved memory leaks for user-created structures, C++ iterators solve bounding problems, and most of the troublesome libraries (generally C libraries that deal with unbounded arrays) have modern replacements that ensure everything remains bounded to prevent overflow.

C is certainly more exploitable then modern C++, but that's by design. Drivers/embedded code have maximal performance requirements, and all those extra memory safety checks bleed performance. That's why it's not only not going anywhere, but is actually *gaining* usage again as the alternatives fall out of favor.
 
  • Like
Reactions: jbo5112
Status
Not open for further replies.