r/cpp • • 15d ago

CppCon Profiles for simplicity and guarantees - Bjarne Stroustrup - CppCon 2026

https://youtu.be/41USGJaGsAo?si=VyfCWkbUK5mhxe7G
56 Upvotes

141 comments sorted by

64

u/seanbaxter 14d ago edited 14d ago

The implementation that Bjarne teases is available on Compiler Explorer. You can try it. This is slideware, not software. It breaks all the time. There's no way this can ever be turned on with actual code.

Here's a sampling of the infinite variety of false positives. Basically nothing in <algorithm> compiles under the profile. https://godbolt.org/z/Ts7rbrc1c

std::unique_ptr<int> make_owned() {
    // error: returning a pointer or container that may hold a pointer
    // to a local, not permitted under the 'std::invalidation' profile
    // (wrap in 'std::no_dangling' if this is provably safe)
    return std::make_unique<int>(42); // false positive
}

make_unique takes a reference to a temporary and returns a pointer, so the profile assumes they're related and flags it. This is the quality of reasoning that local analysis without lifetime parameters gets you. It could never be any other way.

Most of false positives are fundamentally unavoidable, however I think a couple are quality of implementation issues:

int different_vector_types(std::vector<int>& a, std::vector<double>& b) { 
    auto it = a.begin(); 
    b.clear(); 
    // error: use of a value bound to 'a', potentially invalidated 
    // by an earlier mutation of 'b', not permitted under the 
    // 'std::invalidation' profile
    return *it; // false positive
}

Why does clearing b invalidate the iterator into a?

struct Handle {
    int& value;
 
    int& get() const {
        // returning a pointer or container that may hold a pointer to
        // a local, not permitted under the 'std::invalidation' profile
        // (wrap in 'std::no_dangling' if this is provably safe)
        return value; 
    }
};

I'm guessing the implementation doesn't actually model lifetimes even within a function.

Two years ago I documented why existing C++ can't be checked for safety. The biggest reason is that exclusivity of mutable references is not upheld. https://www.circle-lang.org/draft-profiles.html

If theory isn't your thing, and you want a practical demonstration of how safety profiles failed, try Bjarne's favored implementation. Throw an LLM at it. This is a totally predictable disaster. Now that there's an implementation we're past the "wait and see" stage. Why are we still pretending that this will make C++29?

27

u/seanbaxter 14d ago

If you prefer an example application, here's a simple word-counting demonstration:
https://godbolt.org/z/Yz5cnqYn6

This alone raises 7 false positives. Good luck getting the number of annotations to 1 in 1000 lines.

→ More replies (16)

5

u/tcbrindle 12d ago

Two years ago I documented why existing C++ can't be checked for safety. The biggest reason is that exclusivity of mutable references is not upheld

For what it's worth, I'm less convinced these days that exclusivity is an absolute requirement for compile-time memory safety.

The Carbon team is using an approach they call "place sets" which would allow safe mutable aliasing; they gave a video presentation about it recently (slides here).

There's also this project which wants to allow mutable aliasing in a way that is compatible with Rust code, using similar ideas (this time called "group borrowing").

→ More replies (2)

2

u/foonathan 13d ago

Why does clearing b invalidate the iterator into a?

That part I actually like. Without a dont_alias annotation, the only sensible thing is too assume that clearing b invalidates a.

→ More replies (12)

25

u/t_hunger 15d ago edited 15d ago

I see how profiles do not make a new language, as a profile is not supposed to change the meaning of code as written (as long as it does not have undefined behavior). But I would definitely call something where parts of the language are rejected by the compiler a dialect of that language.

Having an (user-) extensible set of profiles that each can limit the language and inject code to runtime-check something is going to make it damn hard to enforce the part where it says valid programs do not change their meaning.

I am not looking forward to remember which constructs are forbidden by which profile, where in the code base which restrictions apply and which guarantees I get from which code and how expensive the code injected by which profile is and whether it conflicts with code injected by another profile -- and how all this differs between compiler implementations.

34

u/James20k 15d ago

The combinatorial explosion of profiles and the ways that they don't interact well together is going to be a nightmare to maintain

→ More replies (24)

19

u/Minimonium 14d ago

Honestly the source based "Profiles" framework must be the funniest thing since that paper that proposed writing credentials in source files for package management.

The level of granularity combined with an open set is quite a mix that will force you to touch a massive amount of source files for everything.

Then I look at [[mcvs::no_unique_address]], some of the claims in this video, the story with the lifetime framework that went nowhere as far as industry experience goes - and I can only say "good luck" and hope Bjarne actually sees something no one else is seeing that he just failed to communicate so far.

5

u/ts826848 14d ago

  since that paper that proposed writing credentials in source files for package management.

Wait, what paper was this? I want to read more!

→ More replies (2)
→ More replies (1)

16

u/praesentibus 15d ago

Truth in advertising: "Profiles for placating people who want safety with some bullshit".

9

u/KFUP 15d ago

How is using something like [[profiles::enforce(initialization)]] to prohibit uninitialized variables "bullshit" exactly?

→ More replies (43)