gpt4 book ai didi

c - GCC 宏 1 + 1 不等于 2?

转载 作者:太空宇宙 更新时间:2023-11-04 00:18:12 25 4
gpt4 key购买 nike

我正在为使用 GCC 编译的 Tiva C 系列 Launchpad 定义寄存器。

在头文件中我有如下代码:

示例 A

#define GPIOB_BASE 0x40005000
#define GPIOB_AFSEL_R (*((unsigned long *) GPIOB_BASE + 0x420))
#define GPIOB_DEN_R (*((unsigned long *) GPIOB_BASE + 0x51C))
#define GPIOB_PCTL_R (*((unsigned long *) GPIOB_BASE + 0x52C))

为了检查它是否按照我的预期运行,我编写了这个小程序,它按预期返回了“10”。我继续我的项目,很快就遇到了硬故障(写入不可写地址)的巨大问题。

宏测试

#include <stdio.h>

#define BASE 0x9
#define BASE + PLUS_ONE 0x01

int main(void){
printf("%d", PLUS_ONE);
}

经过几个小时的调试,我最终用硬编码的等价物替换了地址。

样本 B

#define GPIOB_BASE 0x40005000
#define GPIOB_AFSEL_R (*((unsigned long *) 0x40005420))
#define GPIOB_DEN_R (*((unsigned long *) 0x4000551C))
#define GPIOB_PCTL_R (*((unsigned long *) 0x4000552C))

硬故障消失了,一切开始正常工作了!

谁能帮我理解示例 A示例 B 之间的区别?

(是的,我应该更加关注生成的汇编代码)

最佳答案

指针运算不是以字节为单位进行的,而是以所指向的对象为单位进行的。

在您的例子中,unsigned long。所以这个:

 ((unsigned long *) GPIOB_BASE + 0x420

将产生地址 0x40005000 + 0x420 * sizeof (unsigned long)。假设一个 32 位的 long,那将是 0x40006080,这显然不是您想要的。

你应该把宏写成

#define GPIOB_AFSEL_R (*(unsigned long *) (GPIOB_BASE + 0x420))

现在,加法发生在两个整数之间,然后将结果转换为指针并取消引用。赢得多。

关于c - GCC 宏 1 + 1 不等于 2?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26629910/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com