c - Is this a violation of the strict aliasing rule? -
consider c code:
extern void checkifptrinheap( void* p ); void takeptr( void** p, size_t n ) { for( size_t = 0 ; < n ; ++i ) checkifptrinheap( p[ ] ); } typedef size_t val_t[ 6 ]; extern void* stack_top; void func() { val_t val; takeptr( (void**) &val, ( (size_t) stack_top - (size_t) &val ) / sizof( size_t ) ); } it compiles fine gcc 4.8, mingw 4.7, cl 18.00. might create sense because looks of i'd there no violation here: yes there 2 pointers pointing same variable, sec one's value cast size_t requires temporary, pointer cannot used within function takeptr.
q1: assumption above correct? , if is, mean there no violation, or rather compiler figured out there none while techically (i.e. next standard letter) there violation (still 2 pointers same variable beingness dereferenced)?
q2: stumbled upon while using mingw cross-compiler version 4.2.1 on linux, raises warning: dereferencing type-punned pointer break strict-aliasing rules line takeptr. sec question first in other words: compiler correct, or bug, or 1 rather phone call 'compiler beingness strict'?
q3: wanting compilation without warnings aforementioned compilers, right prepare in code (maybe not case, more general 1 there violation of rule , void** pointers used)? seems there multiple ways quiet compiler:
union { val_t* r; void** ptr; } cast_ = { &val }; void** ptr = cast_.ptr; or
void* p1 = (void*) &val; void** ptr = &p1; or even
void** ptr = (void**) (void*) &val; or maybe (to tell compiler 'hey know i'm doing', @ to the lowest degree if understood restrict correctly)
void* restrict p1 = (void*) &val; void** ptr = &p1; or
val_t* p1 = &val; void** p2 = null; memcpy( p2, p1, sizeof( p1 ) );
strict aliasing rules fact illegal access object of 1 type through lvalue of type (with exceptions things void* , char*, , other obvious things). no more, no less.
merely having two, or three, or 10000 pointers same object @ same time, whether of same type or not, has nil strict aliasing rules. need dereference 1 of them violation happen.
this totally unrelated restrict keyword, not concerned types @ all, informs compiler pointer unique.
takeptr in violation regardless of games played sec argument, because accesses array of size_t if array of void*.
unions won't help, because assignment 1 field of union , accessing field of type not legal either. exactly same bad things happen when dereferencing wrong pointers, happen in case too.
the semi-correct way access value through lvalue of different type via memcpy. not results of automatically well-defined. bit pattern represents valid value of type may not represent valid value of type b. if not case, can memcpy , guaranteed deliver right value.
c gcc c99 type-punning
No comments:
Post a Comment