Wednesday, 15 April 2015

c - Is this a violation of the strict aliasing rule? -



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