1

我正在阅读 USB Wi-Fi 卡的 C 驱动程序代码,并且遇到了我不确定我是否完全理解的部分。我怀疑是我对 C 语言和运算符优先级的理解是错误的,并且驱动程序代码很好,但我想检查一下。

In/drivers/net/wireless/rtl818x/rtl8187/dev.c是一些将一堆值读入 14 元素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 = ...增加通道指针,从而从通道元素开始并缺少元素。此外,无论执行哪个 if/else 分支,我都会计算 14 次对 的调用,所以我会认为最后一次调用实际上会指向(不存在)并覆盖任何变量的内存。堆栈。谁能指出我的解释可能出错的地方?[1][0](*channel++)...(*channel++)channel[15]channels

4

2 回答 2

1
`*频道++`

解释: 1) *channel 即存储在通道中的地址的值被处理。2) 通道的分号地址递增后。

以上是后期增量的步骤。

因此,

    对于(我=0;我

“CAN”仅表示通道是否已经位于位置 0(零)

频道[0].hw_value = xyz; 频道++;
于 2012-09-10T05:17:26.273 回答
0

C 的运算符优先级规则表明后缀运算符的优先级高于一元运算符。因此表达式等价于

*(channel++)

首先需要注意的是指针通道需要增加 1 个单位。由于后缀增量的性质,此更改直到操作数本身被评估后才会发生。

接下来它获取操作数的内容,它仍然是通道。它对内容做一些事情,然后一旦完成,指针就会增加。

现在,为了挑剔,这段代码依赖于未定义的行为,因为变量通道被修改了两次,中间没有序列点。严格来说,代码可以随意乱码,但实际上所有编译器都以确定性的方式实现此代码。

于 2012-09-10T06:43:08.273 回答