On 12/21/23 2:25 PM, Frederick Virchanza Gotham via Std-Proposals wrote:


On Thursday, December 21, 2023, Ville Voutilainen wrote:

The implementation can do anything, including throwing an exception.


Okay I understand now. The implementation will only violate the Standard after you as the programmer have warranted it to do so by invoking undefined behaviour (and therefore it's not really violating the Standard because it can do whatever it likes).

To be doubly sure and deliberately paranoid, when writing portable code to run on everything from an 8-Bit single-core microcontroller to a multi-core 64-Bit supercomputer, maybe wrap 'std::align' in a wrapper that catches and calls terminate. (I mean just to cover yourself sort of like casting to an 'unsigned char' before invoking 'std::tolower').

Personally when I'm writing bullet-proof code, I just put many 'assert's throughout the code. I would assert that a vector is non-empty before calling 'front()'. If I want to handle bad input from the user or corrupt data from a socket, I throw an exception. I don't see myself ever waiting for UB to be invoked and then relying on a particular implementation's flamboyant use of its warrant to do whatever it wants. The whole Lakos thing isn't my cup of tea, but hey it seems a lot of intelligent people like it.

Hopefully C++ contracts will appeal more to your tastes. It will enable similar programming to what you just described by specifying preconditions/postconditions on declarations that behave similarly to an assert at the start/end of the function body. Unlike assert though, there is a handler that enables custom handling (determined at link time so as not to add yet another attack vector) that, by default will terminate the program like assert does, but can be customized to do something like throwing an exception (for those that really need or prefer exceptions over termination). You can, of course, continue using assert.

Tom.


When I want to torture test a program of mine, I use a cross-compiler to build it for 32-Bit Big Endian ARM, and then I run it in the Qemu CPU emulator on my 64-Bit Little Endian x86 desktop PC. If the emulator runs the program perfectly then I'm probably onto a winner.

One day I'd love to write a very bizarre CPU emulator and compiler that does all sorts of weirdness:

    sizeof(char*) > sizeof(int*)
    negative numbers == One's Complement
    CHAR_BIT == 11
    integer types contain padding bits
    null pointer is all bits 1

I'd use this setup to torture-test programs.