Jest przykładowo następująca funkcja kopiująca blok pamięci:
void *
copy( void *dst
, void *src
, unsigned l
){ assert(( char * )dst < ( char * )src || ( char * )dst >= ( char * )src + l );
char *dst_c = dst, *src_c = src;
for( unsigned i = 0; i != l; l++ )
{ *dst_c = *src_c;
dst_c++;
src_c++;
}
return dst_c;
}
Jednak może być ona wywołana copy( dst, dst, l );
. Wtedy zacznie kopiować niepotrzebnie ten sam blok na ten sam blok.
Gdzie sprawdzać, czy wykonywać to kopiowanie:
- przed wywołaniem funkcji
if( src != dst )
copy( dst, src, l );
- w funkcji
void *
copy( void *dst
, void *src
, unsigned l
){ assert(( char * )dst < ( char * )src || ( char * )dst >= ( char * )src + l );
if( src == dst )
return dst + l;
char *dst_c = dst, *src_c = src;
for( unsigned i = 0; i != l; l++ )
{ *dst_c = *src_c;
dst_c++;
src_c++;
}
return dst_c;
}
?
A może jeszcze w jakiś inny sposób?
Chodzi mi o takie rozwiązanie, które nie tylko bedzie poprawne, lecz nie będzie spowalniać programu przy zagnieżdżaniu takich funkcji, ale też wygodne dla pisania programu.
Są dwa rodzaje parametrów: te nieakceptowalne, sprawdzane powyżej instrukcją assert
i te dopuszczalne, ale puste w wykonaniu.