我正在阅读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]
的任何变量的内存。任何人都可以指出我在解释中可能出错的地方吗?
答案 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个单位。由于后缀增量的性质,此更改不会在操作数本身被评估之后发生。
接下来它获取操作数的内容,它仍然是通道。它对内容做了一些事情,然后一旦完成,指针就会增加。
现在,为了挑剔,这段代码依赖于未定义的行为,因为变量通道被修改两次而中间没有序列点。严格来说代码可以随意乱码,但实际上所有编译器都以确定的方式实现这些代码。