以下Linux驱动程序C代码是否有一个错误?

时间:2012-09-10 04:43:40

标签: c

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

/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 = ...会在解除引用之前增加通道指针,从而从元素[1]开始通道和缺失元素[0]。此外,无论if / else分支执行哪个,我都会对(*channel++)...进行14次调用,因此我认为对(*channel++)的最终调用实际上将指向(不存在){ {1}}并覆盖堆栈中跟随channel[15]的任何变量的内存。任何人都可以指出我在解释中可能出错的地方吗?

2 个答案:

答案 0 :(得分:1)

`*channel++`

解读: 1)*信道,即存储在信道中的地址的值被处理。 2)通道的半冒号地址递增后。

以上是后期增量的步骤。

因此,


    for(i=0;i

"CAN" simply mean if channel is already at position 0 (zero)

channel[0].hw_value =xyz; channel++;

答案 1 :(得分:0)

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

*(channel++)

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

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

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