org-howto/lessons/ls2r.org
2024-06-08 16:10:54 -04:00

2.1 KiB

Things that surprised me

#

#

#

#

Introduction

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

c++

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.