1

USB Wi-Fi カードの C ドライバー コードを読んでいて、完全に理解できない部分に遭遇しました。C 言語と演算子の優先順位についての私の理解が間違っていて、ドライバー コードに問題がないのではないかと思いますが、確認したいと思いました。

一連の値を 14 要素の配列に/drivers/net/wireless/rtl818x/rtl8187/dev.c読み込むコードがあります。channels関連するコードdev.cは次のとおりです。

    channel = priv->channels;
    for (i = 0; i < 3; i++) {
            eeprom_93cx6_read(&eeprom, RTL8187_EEPROM_TXPWR_CHAN_1 + i,
                              &txpwr);
            (*channel++).hw_value = txpwr & 0xFF;
            (*channel++).hw_value = txpwr >> 8;
    }
    for (i = 0; i < 2; i++) {
            eeprom_93cx6_read(&eeprom, RTL8187_EEPROM_TXPWR_CHAN_4 + i,
                              &txpwr);
            (*channel++).hw_value = txpwr & 0xFF;
            (*channel++).hw_value = txpwr >> 8;
    }

    ....


    if (!priv->is_rtl8187b) {
            for (i = 0; i < 2; i++) {
                    eeprom_93cx6_read(&eeprom,
                                      RTL8187_EEPROM_TXPWR_CHAN_6 + i,
                                      &txpwr);
                    (*channel++).hw_value = txpwr & 0xFF;
                    (*channel++).hw_value = txpwr >> 8;
            }
    } else {
            eeprom_93cx6_read(&eeprom, RTL8187_EEPROM_TXPWR_CHAN_6,
                              &txpwr);
            (*channel++).hw_value = txpwr & 0xFF;

            eeprom_93cx6_read(&eeprom, 0x0A, &txpwr);
            (*channel++).hw_value = txpwr & 0xFF;

            eeprom_93cx6_read(&eeprom, 0x1C, &txpwr);
            (*channel++).hw_value = txpwr & 0xFF;
            (*channel++).hw_value = txpwr >> 8;
    }

このコードに関する私の懸念は、への最初の呼び出しが逆参照する(*channel++).hw_value = ...に channel ポインターをインクリメントし、それによってchannels の要素から開始し、 element が欠落していると考えていたことです。また、どの if/else ブランチが実行されるかに関係なく、 への 14 回の呼び出しを数えるので、 への最後の呼び出しは実際には (存在しない) を指し、たまたま後に続く変数のメモリを上書きすると考えていたでしょう。スタック。私の解釈のどこが間違っていたのか、誰か指摘できますか?[1][0](*channel++)...(*channel++)channel[15]channels

4

2 に答える 2

1
`* channel ++`

解釈:1)*チャネル、つまりチャネルに格納されているアドレスの値が処理されます。2)チャネルのセミコロンアドレスがインクリメントされた後。

上記はポストインクリメントのステップです。

したがって、

    for(i = 0; i

「CAN」は、チャネルがすでに位置0(ゼロ)にあるかどうかを意味します

channel [0] .hw_value = xyz; channel ++;
于 2012-09-10T05:17:26.273 に答える
0

C の演算子の優先順位規則では、後置演算子は単項演算子よりも優先順位が高いとされています。したがって、式は次と同等です

*(channel++)

最初に、ポインタ チャネルを 1 単位インクリメントする必要があることに注意してください。後置インクリメントの性質上、この変更はオペランド自体が評価されるまで行われません。

次に、まだチャネルであるオペランドの内容を取得します。コンテンツで何かを行い、それが完了すると、ポインターがインクリメントされます。

ここで、うるさいことに、このコードは未定義の動作に依存しています。これは、変数 channel が間にシーケンス ポイントなしで 2 回変更されているためです。厳密に言えば、コードは自由に混乱しますが、実際にはすべてのコンパイラがこのコードを決定論的な方法で実装します。

于 2012-09-10T06:43:08.273 に答える