Sujet : Re: Constants and undefined behavior
De : ram (at) *nospam* zedat.fu-berlin.de (Stefan Ram)
Groupes : comp.lang.cDate : 14. Jun 2026, 18:22:22
Autres entêtes
Organisation : Stefan Ram
Message-ID : <UB-20260614180434@ram.dialup.fu-berlin.de>
References : 1 2 3 4 5
cross@spitfire.i.gajendra.net (Dan Cross) wrote or quoted:
I'm not a huge fan of Carruth.
(Text after "| " below was generated by a chatbot asked to explain
narrow contracts and the reduction of efficiency by defining UB.)
(Let me guess: You are not a huge fan of chatbots either!
Ok, that was easy.)
Chandler talked about how narrow contracts allow optimizations.
| - Wide Contract: The function guarantees to handle all possible inputs
| gracefully, usually by returning an error code or throwing an
| exception. (e.g., "If the pointer is null, return ERR_NULL_PTR").
|
| - Narrow Contract: The function only guarantees correct behavior if
| the caller meets specific preconditions. If the preconditions are
| violated, the behavior is undefined.
|
| When is it appropriate to have a narrow contract? Always, when
| performance, memory footprint, or direct hardware control are
| paramount. In operating system kernels, embedded systems, real-time
| applications, and high-performance computing, the overhead of
| validating every pointer, checking every array bound, and verifying
| every integer range is unacceptable. C assumes the programmer is
| competent and knows the state of their own data. Narrow contracts
| shift the burden of correctness from runtime execution to compile-time
| reasoning and programmer discipline.
Chandler also explained how defining UB for certain operations
would require less efficient code to be generated.
| The hardware: Some architectures silently wrap on overflow, some trap
| and halt the CPU, and some have no concept of the operation at all.
| Forcing a single, defined behavior (like "always wrap around") would
| require compilers to insert expensive emulation code on architectures
| that don't support it natively, destroying C's "trust the hardware"
| philosophy.
|
| Or, consider a loop:
|
| for (int i = 0; i < n; i++) {
| arr[i] = 0;
| }
|
| If out-of-bounds array access had defined behavior, the compiler would
| have to insert a bounds check ("if (i >= array_length)") on every single
| iteration. Because out-of-bounds access is UB, the compiler can assume
| n is always within bounds. This allows it to unroll the loop,
| vectorize it using SIMD instructions, and process 8 or 16 elements per
| CPU cycle, yielding massive performance gains.
Well, there are some tests that can be taken out of loops (as
in Java), but other tests can't.
Haut de la page
Les messages affichés proviennent d'usenet.
NewsPortal