関数を使用すると、ある一定の長さのchar *
パラメータを別の整数型のポインタとして解釈し、その変換されたポインタにアクセスする正当な方法がありますか?次の関数のプロトタイプ与え例えばchar *を読み取り専用操作のための別のプリミティブ型の配列として再解釈する正当な方法はありますか?
...それを行うには違法(UB)の方法の多くがあるように思える:
int32_t sum_32(char *a, int len);
私はの方法があるかどうかを知りたいのですが
合法的に、次のコードと機能的に同等なものを書いて:もちろん
int32_t sum_32(char *a, int len) {
assert(len % 4 == 0);
int32_t total = 0;
for (int i = 0; i < len/4; i++) {
total += ((int32_t *)a)[i];
}
return total;
}
を、ただ大きい値に再結合するためにシフトして文字サイズのアクセスにアクセスを打破するためにそれを行うための一つの方法は、(約いくつかの前提でe
int32_t sum_32(char *a, int len) {
assert(len % 4 == 0);
int32_t total = 0;
for (int i = 0; i < len; i += 4) {
int32_t val = (int32_t)
(a[i+0] << 0) +
(a[i+1] << 8) +
(a[i+2] << 16) +
(a[i+3] << 24) ;
total += val;
}
return total;
}
...しかし、ここで私は一度に基になる配列1 int32_t
にアクセスするソリューションを探しています:ndianness、ここLE)を仮定。
char *a
のソースが割り当て機能であることを知っている場合、答えは「変更できません」、またはより広義にはa
に追加できる制限がありますより大きなタイプは正当なものですか?
最初の問題はおそらく整列です。割り当て関数から来た場合は、少なくとも、それが何かのために適切に整列されていることを知っています。 – melpomene
stdlibのGNU実装を見てみることをお勧めします。文字列関数には、この種の単語単位の処理が多数含まれています。 (整列が行われた後はもちろん) – wildplasser
すでに書いたように、整列とエンディアンに注意する必要があります。たとえば、[この回答](http://stackoverflow.com/a/4840428/69809)には、4または8を法とするポインタ・アドレスを四捨五入するための2つの関数があります。異なるエンディアンを扱う必要がある場合は、同様に個々のバイトを扱うこれは「パフォーマンス」というタグが付けられているので、あまりにも早く最適化していないと確信していますか?後者の関数は、シフト、btwを持っていません。 – Groo