With const references you never have this problem.
With const references you never have this problem.
Const references are less offensive, but I'm not going to pass non-const by pointer and const by reference, that's just inconsistent for no reason.
If null is not a valid value, throw an assert at the beginning of the function. It's not like references can't be in a broken state, they're just syntax sugar for pointers (that also happens to wildly complicate the language's type system)
Why use pointers at all? Just use const references for immutable stuff, regular references when you want mutation, normal values when you want copy semantics, and smart pointers for other cases (unique_ptr for move semantics, shared_ptr for lack of clear ownership, etc.) If you want to represent nullability, std::optional is a good choice.
> If null is not a valid value, throw an assert at the beginning of the function
Yikes. This means the compiler will not catch it for you. Why make this a runtime issue? Use the type system to your advantage.
As for smart pointers there's a lot of domains with tight performance requirements where you can't afford them - and to be quite frank, if you can afford to use shared_ptr you can also afford GC, so just use a sane language
How? Honestly curious. (You can certainly reinterpret_cast something and ignore all warnings, but is that all?)