UP | HOME

Things that surprised me

Table of Contents

1. Introduction

In other words: Principle-of-Least-Surprise violations, according to Roland. Not necessarily flaws.

2. c++

2.1. empty structs have non-zero size

Venerable standard requirement (inherited from C).

Standard requires that distinct variables always have different addresses.

Consider this example:

#include <array>

using foo = struct {};

void loop() {
    foo v[100];

    foo * p = &(v[0]);
    foo * e = &(v[100]);

    for (; p != e; ++p) {
        // do something
    }
}

If foo has zero size, and presumably foo[100] also has zero size, then the for-loop executes zero times instead of 100, which isn't likely to be what programmers expect.

The price of this consistency is that now sizeof(foo[100]) is at least 100 bytes.

Starting in c++20, we can mitigate this somewhat:

struct bar {
    [[no_unique_address]] foo empty1, empty2;
    int counter;
};

The unique address requirement still applies to variables of the same type, so bar::empty1 and bar::empty2 will have different addresses.

However, variables of different types can have the same address, as long as one of them has the no_unique_address attribute.

Author: Roland Conybeare

Created: 2024-09-08 Sun 18:01

Validate