Document Number: N2484 
        Submitter: Aaron Peter
          Bachmann 
        Submission Date: 2020-02-19 
        Make pointer type casting useful without negatively impacting
        performance
      
Pointer-type-punning is useful but mostly
        undefined behavior according to the standards ISO/IEC 9899:1999
        ... ISO/IEC 9899:2018. 
        Before that there were implementation defined aspects. Therefore
        we have to resort to additional - non-portable - extensions
        compiler normally provide or use another programming language
        (often assembler) or work-arounds to achieve our intended goals
        as programmers. Strict aliasing rules are also useful. They
        allow for more efficient code without extra work for the
        programmer. We can allow type-punning in many cases without
        negatively impacting performance. 
memset(), memcpy(),
                strlen(), strcpy(), ... malloc() and friends shall
          be implementable in plain Cmemcpy() is a canonical
                righteous way to deal with the representation of
                objects, but it has its problemsmemcpy()
                  introduced. The programs become harder to read,
                  the number of source lines increases, the programs
                  become less efficient in terms of runtime, code-size,
                  stack-consumption, latency.
                  memcpy() cannot reasonably be used in an
                  implementation of memcpy().
                  memcpy(), then memcpy()
                  must not reside in the same flash - often the only
                  one. If code and data are both in RAM they may compete
                  for the same bus introducing additional inefficiency.
                  memcpy() which
                has to be able to copy objects of arbitrary type. 
restrict.
-fno-strict-aliasing.
        Some C-compilers assume no strict aliasing either by default or
        as the only option: pcc, tcc, the original C-compiler by DMR,
        Microsoft C-compilers, ... -fno-strict-aliasing.via
            attribute((__may_alias__)) 
Make object-pointer-casting (casting a
      pointer-type to a pointer to a different  type)  valid
      and well defined in a local scope, i. e. function-scope and
      block-scopes within a function, provided that the value of the
      pointer derived from the original pointer via the cast to a
      fundamentally different pointer does not escape the scope. The
      accesses via this pointer shall be valid as well, provided we
      honor other restrictions (const, alignment, ...).
    
    #include <limits.h>   
      
          void f1(float **f, unsigned **u){
             
      _Static_assert(sizeof(float)==sizeof(unsigned),"precondition
      violated");
             
      _Static_assert(4==sizeof(unsigned),"precondition violated");
             
      _Static_assert(8==CHAR_BIT,"precondition
      violated");        
                    unsigned u32;
                #ifdef DO_SOMETING_INVALID 
              *f=*u; // invalid        *u=*f; // invalid
                *f=*(float**)u; //
        invalid       
            *u=*(unsigned**)f; // invalid   
            #else
                (void)u;
           #endif
            
                   
            u32=**(unsigned**)f;
                   
            u32^=1u<<31;
                    // under the
            restrictions given above a compiler not seeing the
            implemention
                    // of the
            function but its prototype only must already assume
                    // **f may be
            changed (as float); in this case **f=-**f
                    **f=(float)u32;
            // valid according to the proposal
                } 
      
    #include <string.h>
#include <limits.h>
#include <stdint.h>
#define ALIGN (sizeof(size_t))
#define ONES ((size_t)-1/UCHAR_MAX) // 0x01010101 for 32 bit integer
#define HIGHS (ONES * (UCHAR_MAX/2+1)) // 0x80808080 for 32 bit integer
#define HASZERO(x) ((x)-ONES & ~(x) & HIGHS) // only 0 has OV & high bit 0
size_t strlen(const char *s){
const char *a = s;
const size_t *w;
for (; (uintptr_t)s % ALIGN; s++) if (!*s) return s-a;
// harmless but undefined, because we eventually read more than object-size!
#ifdef STRLEN_USE_MEMCOPY
// pray compiler will remove memcpy()
for (;memcpy(&w,s,sizeof(size_t)), !HASZERO(*w); s+=sizeof(size_t));#else
for (w = (const void *)s; !HASZERO(*w); w++);// code matching this proposal
s = (const void *)w;
#endif
for (; *s; s++);
return s-a;
}
static float *Fp=(float*)&Something;static unsigned *Uu=(unsigned*)&Something; // invalid
for example:For portable programs [u]int32_t
                must be assumed to alias any integer type,  except
                for long long, since it could be int
                or long and almost any other integer-type.
                short can have 32 bits. The same applies
                for other [u]intx_t-types.malloc(). For that we have to
                allow aliasing in other situations as well. This too may
                be possible without significantly restricting the
                usefulness of strict aliasing. This bullet point only
                sketches a potential loophole.  char*.
                If we also allow to access any object of char*
                via any_type* we can implement malloc()
                and friends. This would still not allow to alias
                any_type1* with any_type2*
                provided any_type1* and any_type2*
                are mutually different and different from char*.
                Within the lifetime of the object pointed to by char*
                we would allow char* to alias any_type1*,
                any_type2*,... but the use of the aliases any_type1*,
                any_type2*,... must be sequenced. 
An object shall have its stored value accessed only by an lvalue
      expression that has one of the following types:89)