2016-12-15 5 views
1

コード:このようなポインタをキャストできますか?

unsigned char array_add[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; 

... 

if ((*((uint32_t*)array_add)!=0)||(*((uint32_t*)array_add+1)!=0)) 
{ 
... 
} 

私は、アレイがすべてゼロであるかどうかを確認したいです。当然、私は配列のアドレスをキャストすることを考えました。これは、最初のメンバのアドレスでもあり、unsigned int 32型になりました。したがって、これを2回行う必要があります。これは、64ビット、8バイトアレイ。問題は、正常にコンパイルされましたが、プログラムがここで毎回クラッシュすることです。

私は8ビットマイクロコントローラ、cortex-M0でプログラムを実行しています。

私は間違っていますか?

+1

このようなコードの作成をやめてください!それはトラブルを呼び起こすように見える。キャストが未定義のビヘイビアを呼び出すことを考慮する。なぜあなたは 'uint32_t [2]を使わないのですか? – Olaf

+1

Cortex-M0は8ビットCPUではありません! – Olaf

+0

ポインタを使用するだけの理由はありますか? unsigned char * pt = array_add; if((*(pt)!= 0)||(*(pt + 1)!= 0)) – dante

答えて

-3

私はわかりませんが、あなたの配列が8つのバイトを持っているならば、ちょうど配列がすべて0

編集1であるかどうかをチェックするのあなたの問題を解決する必要があることをlong long変数にベースアドレスを割り当て、0にそれを比較しますOlafのコメントの後、私はlong longint64_tに置き換えて言うでしょう。しかし、なぜあなたは配列の繰り返しとチェックのための単純なループではありませんか?あなたが比較する必要があるのは8文字です。

編集2:もう1つのアプローチは、配列のすべての要素をORし、次に0と比較することです。すべてが0の場合、ORはゼロになります。私は、CMPが高速であるかORであるかはわかりません。正確なCPUサイクルの要件については、Cortex-M0のドキュメントを参照してください。ただし、CMPが遅くなることが予想されます。

+0

'long long'は64ビットを保証するものではありません!ちょうどOPの正しいことは、固定幅のタイプを使用しています。 – Olaf

+0

ページ番号n1570.pdfの28は、long longは64ビットを必要とする最小範囲を持っていると言います。 'long long'が64ビットであるとは保証されていないと言われている場所に私を紹介してください。私は仕様上他に何かを忘れましたか? – user902384

+2

あなたは既に該当する部分を引用しました!もう一度注意深く読んでください! – Olaf

2

理論的にはこれはうまくいくかもしれませんが、実際には考慮していないことがあります。

uint32_t場合は、次にuint32_t*に1つのバイトアライメント要求を有す​​るunsigned charのアレイを鋳造するuint32_tの非整列配列へのポインタを生成し、(4バイトなど)に整列メモリアクセスを必要とします。 documentationによると

のCortex-M0プロセッサのアンアラインドアクセスはサポートされていません。アラインされていないメモリアクセス操作を実行しようとすると、HardFault例外が発生します。

これは実際には、特定の状況では定義されていない動作を呼び出すOlafによって指摘されており、よりよく説明されたhereのように危険で壊れやすいコードです。

+1

このコードはまた、有効な型の規則に違反し、UBを呼び出します(そのうちの1つは** 1つの**問題、他はコンパイラの最適化を含みます)。 – Olaf

1

複数のバイトを一度にテストするには、memcmp()を使用します。

これはどのように高速化するかは、最適化コンパイラとしてコンパイラに依存します。これは、一度にクイック8バイト(または2つの4バイト)を比較する簡単なコードです。 memcmp()でも、8ビットプロセッサでは遅すぎるとは限りません。プロファイリングコードが役立ちます。

マイクロ最適化に注意してください。それらは、著しい最適化のためにコーダの時間を効率的に使用しないことが多いためです。

unsigned char array_add[8] = ... 
const unsigned char array_zero[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; 
if (memcmp(array_zero, array_add, 8) == 0) ... 

もう一つの方法は、unionを使用しています。 add.arr8[0]が最上位または最下位バイトであると想定しないように注意してください。一般的に

union { 
    uint8_t array8[8]; 
    uint64_t array64; 
} add; 

// below code will check all 8 of the add.array8[] is they are zero. 
if (add.array64 == 0) 

非常に選択の場合にクリアコードと予備、そのような小さな最適化を書くことに焦点を当てます。

関連する問題