To me talks by practitioners, who have experience in a given field allowing them to know what works and what doesn't, are more compelling. In the past Mike Acton and Chandler Carruth were such speakers. After quickly going over the schedule, this year Ben Saks, Andrew Drakeford, Ivica Bogosavljevic, Eyal Zedaka, Daniel Withopf, Andreas Weis and Ilya Burylov seem to be such speakers. I'll watch their talks when they become available.
Many of those practitioners, do indeed do great talks, but they also live in a bubble far away from 9-5 C++ coders that put out most code.
I advise a CppOnSea 2022 talk, "help me my team is stuck in 90's".
I am not surprised by this lack of understanding of human psychology. People will always do the most simple, natural thing that they learned at some point in their lives. You can't expect them to change overnight or even change at all.
A lot of folks who write C in C++ are old gurus who learned their trade long ago.
Ah, blaming the tools: the Hallmark of a master.
Take a moment to think about the problem. You're in a multi-team project, with a few millions lines of code. You're paid to deliver results and meet the client's requirements, and you're already behind schedule. Suddenly the C++ standard committee releases a new C++ standard. What are you going to do? Are you going to
a) continue working on your tickets, or
b) are you going to drop everything to spend weeks updating tooling, projects, dependencies, and put up a series of workshops with the purpose of getting everyone onboard the new shiny toy?
And did you noticed that option b) adds absolutely no value at all?
It's great that you can flip a flag and turn your hello world project into a C++20 project with no work at all, but real world teams that are in the business of outputting real world production-ready code requires a bit more caution.
For instance, I still recall from a previous project I worked with how a n upgrade to C++14 led a dependency to over-eagerly jump head-on to constexpr which caused weird and non-trivial linking errors that took a week or so to sort out. And constexpr wasn't a new addition in C++14.
Do you think that's an unavoidable law, or is it something accidental that could have gone better?
Would you say a similar minor upgrade of the language version in other languages would have also caused a week of similar hard to debug errors, for a project of the same size?
I'm curious who you blame, if you don't blame the tools. You could try to blame people. Or one might say it's just how things are and we can't do better.
I'm just not sure if you see this as unavoidable, or if it's something else that makes you say that? You got me curious.
It was the result of having to develop production code in the real world, reusing real world production code developed by third-parties.
In my particular case it just so happened that the upstream dependency exported interface headers that conditionally defined stuff with C++14 features in spite of what shipped with their binaries. Stuff using constexpr ultimately resulted in tons of hard to track linking errors.
> Would you say a similar minor upgrade of the language version in other languages would have also caused a week of similar hard to debug errors, for a project of the same size?
This was not a C++ problem. This was a problem caused by the way this particular project was designed to toggle C++14 features when they should not be toggled.
Just because problems emerge when updating a project to the next language version, that does not mean the language is held to blame.
This is one of the reasons why I firmly believe half the people in this thread talking crap about software updates and bumping programming language versions are quite frankly talking about stuff they know nothing about and have zero real world experience. There's far more stuff going on in a language upgrade than flipping a switch and rebuilding a project, specially if upstream dependencies made some less-than-advisable decisions on how to release their work.
In C++ if you aren’t able to build your entire stack of dependencies from source you are gonna have a bad time like this at some point. Any prebuilt libraries you depend on better be pure C, headers included.
I am sure for many of those people, they do this because they have decided that sufficiently understanding the complexities of C++ provides too little payout (or in some cases none at all) to make the shift worthwhile for them. I don't think accusing developers of "being stuck in the 90's" is the right way to convince them to work differently. If the technology is actually better, you should convince them of such by demonstrating it with many concrete examples.
Contrary to what many seem to believe, just because something is new doesn't mean it is better, even when computers are involved.
"I think that the approach I'm talking about with static analysis and rule based... for modern styles can deliver complete safety"
I expect over the next decade or so, a lot more resources will be thrown at unsuccessful attempts to solve this problem.
Maybe I am misunderstanding? Don’t you have to solve inter-procedural pointer aliasing first?
C++ has tons of features, many will say "too many", and it accumulates over every revision. C, by comparison, is simple.
But sometimes C is too simple, it is fine for 99% of your needs, but for the extra 1%, you need C++. If that's the case, just write C and compile it with a C++ compiler so you can take that extra feature you need. Just because you are using a modern C++ compiler doesn't mean you should start using RAII, managed pointers, exceptions, and all these things.
Sometimes it makes sense to go full-on "modern C++", but using C++ literally as "C incremented by one" is a use case that shouldn't be dismissed.
For me, constexpr for resolving complex build-time logic into constants, cleaner type handling for the math library makes it harder to accidentally pull in a 64-bit libm when we only have a 32- it FPU, and templating for sure.
It's pretty easy in C to reach a point where macros of macros is madness but templates calling templates still works with the debugger and is a powerful mechanism for hoisting complexity out of loops. Also works nicely for writing outer loops once in c++ calling a template specialized to either inline assembly or c++.
Managed pointers sometimes but our team seems pretty good with object lifetimes from a C background, and we don't use too much heap anyway.
RTTI and exceptions we often disable to save code space.
RAII is a little tricky without exceptions, we often use it's easy.
With templates, I use them for generics, but also judiciously to create meta-linguistic abstractions to get around certain limitations of language. For example, I built an ORM using them.
I don't use auto, or lambdas, or even foreach (I use iterators), despite oddly having much more dynamic language experience.
I believe people, in general, agree C is too simple of a programming language to actually deal with all the essential complexity of modern software development in various cases.
The actual complaint people have about C++ is that it has too much extra unnecessary accidental complexity due to weird ways features interact.
The analogy of the Surgeon I believe should be adjusted having these two points in mind. Generally speaking, surgeons would agree that "scalpel and whiskey" are too simple of a tool set for doing modern surgery. However, if you take modern surgeon tools and add a bunch of weirdness to them, then surgeons would reject them on the grounds of being more complicated than needed.
> A bad surgeon could also be overwhelmed by the amount of modern tools and use the wrong one.
When this is contrasted with the C++ situation, I believe the comparison would be fair only if all the modern features in C++ had to do with the inherent essential complexity of software development. That is not the case (at all). Expert developers have been talking about how C++ is unnecessarily complicated for ages (before C++03 even; back when things were simpler in terms of weird language feature interactions).
I agree with your overall point, but I feel like RAII is practically the key feature that C++ provides over C (:
Or at any rate, I wouldn't say it is anything to do with "modern C++". It was there from the beginning, and C++'s object lifetime rules are pretty core to the language IMO.
I'm curious, since you phrased it that way: what C++ feature(s) do you tend to reach for first, when moving from C to C++?
But so far I haven't seen any convincing evidence that would prove (or give a high degree of confidence) that it can be done. It this just wishful thinking on Bjarne's part, or is there somewhere I could read on how he thinks that could actually be done in practice?
(I'd be inclined to take their word on it over Bjarne's.)
I'm not sure this is where I originally read their conclusions, but lots of info about this, regardless: https://docs.google.com/document/d/e/2PACX-1vRZr-HJcYmf2Y76D...
Chromium is hardly a compiler or tooling project. Even if their devs aren't hacks, appeals to authority based on their perceived expertise hardly make any sense.
Having said that, there is no better litmus test than showing something working. If Dr Stroudtrup strongly believes in C++'s ability to provide Rust-like memory safety guarantees, there's no better person than him to prove him right (or wrong). If he does not have a proof of concept in the works, he's not in a good position to substantiate his claim.
I don't agree. Chromium is an end-user of compilers and tooling that originated in forking a third-party desktop app. Developing C++ compilers and static code analyzers is way way outside of their wheelhouse. What they can and cannot do outside of their wheelhouse is hardly relevant or representative.
Admittedly my claims about Chromium are based on my observations as an outsider, but as someone who works on tooling (linkers) at a different large company that also has a web engine written in C++ I can tell you it is consistent with what I have seen up close... web engines (and particular JavaScript JITs) tend to push C++ tooling hard and often inspire major investment by the teams working on C++ specifically to support them.
In fact, over the years I have seen a number of people (including C++ committee members) who transitioned back and forth between the C++ compiler teams and the JavaScript JIT teams because they sometimes work very closely together, so in my experience the level C++ expertise on lot of the teams developing web engines tends to exceed anything but the actual C++ tooling teams supporting them, and developing C++ tooling is most certainly in their wheelhouse.
A browser is a much more demanding environment, involving code generation, multithreading, caching, and low-overhead interfaces to complex data structures. Memory safety is extremely hard in that case.
So both could be true.
Visual C++ support for it is pretty much WIP, full of false positives.
It seems a bit off to me to claim it's a superset of C while banning the subset of C.
Like it or not, C++ does have things like raw pointers, null terminated arrays, setjmp/longjmp, and macros. That's part of being a superset of C. Using them in C++ is still C++ if it's compiled by a C++ compiler.
It may not be idiomatic, but I'd love to see the C++ community come up with a single definition for idiomatic C++. And to preempt the answer of "idiomatic C++ is Modern C++" -- How about things like exceptions, rtti, and iostream?
Writing C in C++ means exactly that, writing C++ code in the subset that is also valid C, while ignoring everything else that the language offers regarding type safety, including basic stuff like RAII, or templates instead of macros.
Technically it is C++ code, in practice can be compiled with a C compiler as well.
For starters, write non-idiomatic code which employs (exclusively or not) a subset of features.
Imagine writing Python and only using free functions, while vehemently refusing to use stuff like classes or list comprehension or exceptions or anything at all. Similar to "writing C in C++", this would be "writing shell scripts in Python".
> Like it or not, C++ does have things like raw pointers, null terminated arrays, setjmp/longjmp, and macros. That's part of being a superset of C. Using them in C++ is still C++ if it's compiled by a C++ compiler.
You're missing the whole point.
"Writing C in C++" is synonymous to "not using new C++ features that are safer and faster and better than the old C features".
It's completely irrelevant if the compiler supports raw pointers or preprocessor macros. The whole point is that, say, intentionally using raw pointers when you have smart pointers is hardly justifiable, and you're not doing yourself any favor.
Usually, if one avoids OOP features of Python, that means he/she likes to use more functional features. And vice-versa.
I imagine it's the same with C vs C++. People use malloc/free, classic for loops and structs+functions only because that style fits their mindset better.
C++ is not a superset of C.
I see no evidence that C++ (or any language) can provide the same level of confidence, without having the same sort of support in the language itself. An analysable fragment of C++ might be a thing; rust level guarantees for the whole language is very unlikely.
Where I work, most C code can not be checked in to source control until the CI bot is satisfied with the static analysis run. That's necessary because of C's separate compilation model: static anaylsis requires whole-program analysis to track aliasing.
Rust is a single tool that does (or may do, when opted-in) static analysis. It's not the first, not the only, and probably not the best. Other development environments use separate tools for separate operations. Engineering has always had its lumpers and dividers. Rust and Windows is for lumpers, C and Unix is for dividers.
And they only just barely managed to get something usable in the beginning. Rust ergonomics have improved a lot since 1.0.
The criticism here is that C(++) advocates often claim the language is fine, and static analysis is enough to fix the problems.
Rust is hopefully just a stepping stone to something better, but the assumption that no new language semantics are needed is denial.
An example is I wrote a varadic template for a GC allocation interface:
T1* obj1 = Alloc<T1>(arg1)
T2* obj2 = Alloc<T2>(arg2, arg3)
However because I have so many fine-grained types, this seems to takes up 10% of the VM size of the program!https://www.oilshell.org/release/0.12.5/pub/metrics.wwz/oil-...
The total vmsize is 1217792 and the 2 Alloc<> entries are about 10% of that.
So my conclusion is that it would have been better to use a macro all along, which would look something like:
T1* obj1 = ALLOC(T1, arg1)
T2* obj2 = ALLOC(T2, arg2, arg3)
This will expand to something like: T1* obj1 = new (gHeap.Allocate(sizeof(T1)) (arg1)
That is, it uses placement new to constructs the object inside a GC'd heap.-----
I don't believe the C++ idiom is any faster, and it makes the code larger (and potentially slower).
Am I missing something?
I think the issue is that the monomorphization happens for each T and not for each sizeof(T), and even doing it on sizeof(T) is not really necessary for fast code.
Oil has more fine-grained and ML-style strong types than any other shell implementation, via ASDL and C++. So I try to take advantage of additional type safety. But sometimes it's not worth it. I suspect the macro is better here. It will be somewhat annoying to change all the code, but probably worth it.
template <typename T, typename... Args>
T* Alloc(Args&&... args) {
assert(gHeap.is_initialized_);
void* place = gHeap.Allocate(sizeof(T));
assert(place != nullptr);
// placement new
return new (place) T(std::forward<Args>(args)...);
}
https://github.com/oilshell/oil/blob/master/mycpp/gc_heap.h#...So there is nothing to really break up
So no standard library for you.
Which likely implies "no C++".
Which keeps us writing in C.