1

MISRA ルールに準拠するようにアプリケーションを再構築し、QA-C を使用してコードを分析しています。

これらの煩わしいルールの 1 つに、ポインターと配列が関係しています。あなたは言うことができません:

char foo[10];
char * bar = &(foo[0]);

bar[5] = 'a';

また、次のこともできません。

*bar = 'a';
bar++;

私の問題には、2 つの関数とファイル スコープ変数が含まれます。

元々、このコードは次のことを行いました (ビット疑似コードのように):

static char * bufferPtr;

static void foo_a(char * buffer /* other params */)
{
    bufferPtr = buffer;

    /* some logic goes here */
    switch()
    {
        case 'b':
           foo_b(/* some param */);
}

static void foo_b(/* parameters */)
{
    if (/*something*/)
    {
        /*  some logic */
        foo_c(/* data-param */);
        /* some logic */
    }
    else
    {
        /*  some logic */
        foo_c(/* data-param */);
        /* some logic */
    }
}

static void foo_c(char data)
{
    *buffer++ = data;
}

私はそれを次のように書き直そうとしました:

static char (*bufferPtr)[];
static char bufferIndex;

static void foo_a(char buffer[] /* other params */)
{
    bufferPtr = &buffer;
    bufferIndex = 0;

    /* same */
}

static void foo_b(/* parameters */)
{
    /* same */
}

static void foo_c(char data)
{
    (*bufferPtr)[bufferIndex] = data;
    bufferIndex++;
}

しかし、その後、misra と私のコンパイラ (softune、富士通) の両方が文句を言います。コンパイラは次のように述べています。

CHAR **' toCHAR (*)[]': 演算子 `='からの互換性のないポインタ型の代入

ミスラ 言います:

[C] 代入の右オペランドが互換性のあるポインター型ではありません。リンケージまたはより広いスコープを持つポインターにエクスポートされた自動オブジェクトのアドレス。

ただし、foo_c 関数で配列にインデックスを付けることができる必要があります。または、ミスラに従って、私のコードを機能させる他の方法はありますか。

同じファイルで次のことを行うと:

static CHAR foo[10];
static CHAR (*bar)[];
static void f(void)
{
    bar = &foo;
}

その後、ミスラも私のコンパイラも何も文句を言いません。

4

5 に答える 5

0

これは私には意味がありません:

static char (*bufferPtr)[];
static char bufferIndex;

私はそれをそのようにします:

static char *bufferPtr_new;
static int bufferIndex_new;

そして、すべての*bufferPtrをbufferPtr_new[bufferIndex_new]に置き換えます。しかし、MISRAによると、おそらく現在のコードの何が問題になっているのかを説明してください。

于 2012-07-03T14:19:46.847 に答える
0

これらの煩わしいルールの 1 つに、ポインターと配列が関係しています。あなたは言うことができません: ....

char foo[10];

許可されていない char タイプを除いて、まったく問題ありません。

char * bar = &(foo[0]);

foo が配列構文で宣言されていれば問題ありません。ポインター構文を使用して foo が宣言された場合、ルール 17.4 に違反します。以下のルール 17.4 の修正を参照してください。また、括弧は、MISRA やその他の理由から、まったく意味がありません。

bar[5] = 'a';

まったく問題ありません。

*bar = 'a';

まったく問題ありません。

bar++;

これは、規則 17.4 では許可されていません。規則 17.4 では、配列のインデックス付けがポインター演算の唯一の許可された形式であると述べています。これは非常にばかげたルールであり、MISRA の次のバージョンで削除されると思います。私は実際に委員会でこの規則について話し合ったことがありますが、彼らは化粧品以外の規則の根拠を示すことができませんでした.

解決策は、このルールに対して MISRA-C からの逸脱を作成することです。これは、ほとんどの MISRA 実装で行われているようです。MISRAを盲目的にフォローしないでください。ルールの 90% は適切ですが、いくつかの奇妙なルールには根拠がありません。

于 2012-07-04T11:23:30.657 に答える
0
static void foo_a(char * buffer /* other params */)

引数bufferは配列ではなくポインターなので、他の場所で配列として扱おうとすると失敗します。

賢明なことは、配列へのポインタ(一部の N の場合)または適切なサイズの配列を含むへfoo_aのポインタを受け入れることです。次に、ファイルに静的に割り当てるか、(より良い) 呼び出しチェーンを介して配列ポインターを渡すことができます。char (*buffer)[N]structchar (*bufferPtr)[N]

于 2012-07-03T15:11:44.870 に答える
0

あなたがこれを好きになるかどうかわからない:

static char *(bufferPtr[10]); /* must have a size */
static char bufferIndex;

static void foo_a(char buffer[])
{
    *bufferPtr = buffer;
    bufferIndex = 0;
    /* etc */ 
}

それが役に立てば幸い。

于 2012-07-03T14:45:01.787 に答える
0

このコードの流れを変更して、バッファ パラメータを後続の各バージョンに渡すだけにしました。

醜いですが、機能し、ある程度安全です。「ミスラによると」

于 2012-07-06T10:05:45.673 に答える