2017-03-22 17 views
-3

私は(そうOKである物理アドレスにアクセスして、それはマイクロコントローラ上にある)マクロに対処している(条件付き定義の長いシーケンスの後に、属性など):比較Cマクロ

#define ADDR_A (*18) 
#define ADDR_B (*30) 
#define ADDR_C (*18) 

I

#if ADDR_A==ADDR_C 
    return 1; 
#else 
    return 0; 
#endif 

しかし、私が手:私はコンパイルを最適化することができますので、それらを比較したいと思います:理にかなっている「エラーをオペレータに 『*』は、左のオペランドがありません」。マクロの定義を比較することは可能ですか?私は彼らを何とか比較するために文字列に変換することができる愚かさを持っていますが、私は(マクロ引数のための#と同様に)方法を見つけていません。

いいえ、私はサイクルを数えているので、実行時にこれを行うつもりはありません。

+4

これは有効ではありません。C.コンパイラは、それがアドレスであり、オブジェクトの型がどのようになっているのだろうと思いますか?残りの質問は明確ではありません。あなたは何を比較したいのですか?なぜですか?それはXY問題のようなにおいをします。 – Olaf

+0

私は@Olafと完全に同意します。さらに、私が使用したCコンパイラはすべて、式にリテラル定数のみがある場合(通常は2つのメモリマップレジスタのアドレスを比較する場合と同じように)、通常の 'if'ステートメントを最適化します。マイクロコントローラを使用しているので、とにかく最適化を有効にする必要があります。つまり、関連するコードを最適化するために*プリプロセッサ*に依存する必要はありません。どのような半分のまともなCコンパイラはあなたのためにそれを行います(通常のC 'if'文を使用する場合)。 –

答えて

1

ので、あなたは、#ifで文字列を比較することはできません:あなたが唯一の定数式と#if

  • 文字列のみ
  • ループは」上がらないループや関数を使用して比較することができます使用することができます

    • トン定数式
    • と:

      Constant expressions shall not contain assignment, increment, decrement, function-call, or comma operators, except when they are contained within a subexpression that is not evaluated. (C11, 6.6P3)

    私は考えることができる最高のアドレスと二つの異なるマクロに逆参照を分割することで、のような:「実行時」の定数の平等をチェックするが、ほとんどすべてのコンパイラで省略されること

    #define ADDR_A (18) 
    #define ADDR_B (30) 
    #define ADDR_C (18) 
    #define GET_A (*ADDR_A) 
    #define GET_B (*ADDR_B) 
    #define GET_C (*ADDR_C) 
    
    #if ADDR_A == ADDR_B 
    return 1 
    #else 
    return 0 
    #endif 
    

    注意その塩の価値がある。 this exampleではコンパイラはreturn 1に相当するものを生成します。コンパイル時に条件がfalseと評価されるためです。これらの比較が省略されるため、カウントサイクルはここでは赤いニシンです。

    また、どのようにそれらのマクロを使用しているのかわかりません(私は文法的に有効なところに頭を構えません)が、あなたのコードがマクロにアドレスが含まれているだけで、コード内でそのアドレスをインライン展開すると分かりやすくなります。あなたのコードを読んでいたら、私は大いに好きになるでしょう:

    #define ADDR_A (18) 
    #define ADDR_B (30) 
    #define ADDR_C (18) 
    
    if (ADDR_A == ADDR_B) 
        return 1 
    return 0 
    
  • 1

    マクロ内のアドレスとタイプ情報を別々に入れるのはどうですか?

    #define ADDR_A (18) 
    #define ADDR_B (30) 
    #define ADDR_C (18) 
    
    unsigned uint16_t *A = (uint16_t*)ADDR_A; 
    unsigned uint16_t *B = (uint16_t*)ADDR_B; 
    unsigned uint16_t *C = (uint16_t*)ADDR_C; 
    

    次に、テストを使用できます。また

    、プリプロセッサをスキップして、ちょうどCでそれを行う:

    unsigned uint16_t *const A = (uint16_t*)18; 
    unsigned uint16_t *const B = (uint16_t*)30; 
    unsigned uint16_t *const C = (uint16_t*)18; 
    
    int f() 
    { 
        if (A == C) 
         return 1; 
        else 
         return 0; 
    } 
    

    あなたは極めて低品質のコンパイラを持っていない限り、あなたはそれが定数式としてA==Cを認識し、簡素化することを期待することができますそれに応じてコード。