Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

I think the problem is mostly in the tone of the opening paragraph and less in the list itself. By prefixing this with

"Don’t automatically assume that C++’s situation is desirable, necessary, or inevitable."

It seems to be trying to frame this as C++ having bad duplication. But many of the things listed are not actually strict duplicates at all - like pointers vs. references, since references cannot be null (yeah yeah you can force it but 'int& foo = nullptr;' doesn't compile, either). Which if you then read the explanations at the bottom tend to cover in a fairly non-biased way.



> are not actually strict duplicates at all

Yes, that's probably why the article's title is "Near-duplicate features of C++".

> references cannot be null

From the discussion and examples, that seems to be a restriction on the programmer, not a feature of the feature.


> From the discussion and examples, that seems to be a restriction on the programmer, not a feature of the feature.

Being a restriction and being a feature are not mutually exclusive. Strong typing is a restriction on what's a collection of bits. Functions are just restrictions on your ability to change the PC. Loops are just restrictions on your ability to jump.

Restrictions are necessary to create structure.


"Restriction on the programmer"

as in "it is the programmer's job to make sure this doesn't happen". That's an anti-feature, aka "bug".


> references cannot be null

    void test() {
      int* p = 0;
      int& r = *p;
    }
compiles without complaint.


A failure to issue a warning is not a refutement of the standard. As I said, yes obviously you can force it. You can force just about anything you want in C/C++.

But if you do

   int& r = *((int*)0);
You'll find it will warn, and tell you that what you're doing is illegal:

<source>:2:14: warning: binding dereferenced null pointer to reference has undefined behavior [-Wnull-dereference]

Same if you try to naively return nullptr on a method that returns a reference:

    int& iref() {
        return nullptr;
    }
<source>: In function 'int& iref()':

<source>:6:12: error: invalid initialization of non-const reference of type 'int&' from an rvalue of type 'std::nullptr_t'

    6 |     return nullptr;

      |            ^~~~~~~
Compiler returned: 1


This is not a valid program. The second line invokes undefined behavior. The compiler is legally allowed to replace the null dereference with code that sends your porn collection to your mother, and set the reference to 42.

If you get a null reference, this is by chance and not by design.


> The compiler is legally allowed to replace the null dereference with code that sends your porn collection to your mother, and set the reference to 42.

Although no sane implementation would do this.


No, but they may optimize out assigning to the reference at all, since assigning to it requires dereferencing a provably null pointer, which means that any future code is effectively meaningless.


They wouldn't, but they could very well come to a different sane result on a particular architecture than they implementation/architecture you're on.

And that would be perfectly compiler-legal, and your code would have one free bug.


I've gotten into arguments about this in the past.

As you've shown, references can be null, but theyre not supposed to be and are assumed nearly universally to not be.

The argument comes down to when the undefined behavior occurs: is it at the deference to create the reference, or is it on the first memory access using the reference? The language pedants will say the former, but in practice, it's the latter.

In practice, you'll likely be able to invoke a member function on a null pointer or reference, as long as that member doesn't directly or indirectly access data members, or virtual functions of the type. Obligatory, I dont recommend doing this or relying upon this behavior, it's just behavior I've seen in my 2 decades of debugging C++.


It's mostly important in the context of codifying nullability. If a function returns a reference it's part of the contract that it doesn't return null. Similarly, if a parameter is a reference it's part of the contract that you can't pass it null.

It doesn't mean a method that takes or returns a pointer must allow null as a valid value, of course, Optional<> is better for that. But standards-enforced non-null is a very practically useful aspect of references that differ them from pointers.


> The argument comes down to when the undefined behavior occurs: is it at the deference to create the reference, or is it on the first memory access using the reference? The language pedants will say the former, but in practice, it's the latter.

The undefined behavior is always when the null reference is created. The issue will _usually_ manifest when you try to dereference the pointer, but the undefined behavior was creating the null reference in the first place.


Technically, it's an undefined behaviour. Compilers do what they want in this situation.




Consider applying for YC's Winter 2026 batch! Applications are open till Nov 10

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: