Vidar Hasfjord - 2013-12-09

Proper handling of 64-bit sizes

Proper handling of 64-bit sizes is important for robust 64-bit support. For example, 64-bit sizes arise for memory allocations, standard strings (owl::tstring) and containers (e.g. std::vector), and for file sizes and positions. We have the following options for the handling of 64-bit sizes, sorted by increasing robustness.

  1. Ignore the issue, and document that 64-bit sizes are not supported.
  2. Silently clamp 64-bit sizes to [INT_MIN, INT_MAX].
  3. Support 64-bit sizes where applicable, and assert (in debug builds) where not.
  4. Support 64-bit sizes where applicable, and throw exceptions where not.

For example, many Windows API functions that deal with text, only support a 32-bit size. However, OWLNext uses owl::tstring (and raw arrays) that have 64-bit size. If we ignore this issue, i.e. option (1), sizes will be truncated and cause undefined behaviour, e.g. crashes. Note that truncating a size is not the same as truncating a text. Truncating a 64-bit value gives an arbitrary value in the 32-bit range. This makes option (1) brittle with potentially unexpected results. Option (2), clamping the size to the 32-bit range, has the drawback that it truncates the text. Text truncation is rarely insignificant. Option (3) is unsatisfactory, since the text size is most often determined at run-time, so the issue can not be eliminated in debug builds (asserts should only be used to test programming logic errors). That leaves option (4) as the most robust solution for text.

A similar analysis can be applied to containers and files.

Due to the current state of the OWLNext project, the simplest solution is to adopt option (1), i.e. declare that using 64-bit sizes with OWLNext causes undefined behaviour (UB), unless 64-bit support (or behaviour) is explicitly documented for each function and class. In the long term, option (4) would be desirable.