我正在一个项目中工作,我们有很多内存作为#defines 比如
PersonFactory[R]
如果我使用#define以上,我会收到错误 如果我将其更改为
#define SRAM1 0xb0000000+((1024*1024)-64) //1
有效。 即使这样也可以
#define SRAM1 (0xb0000000+((1024*1024)-64)) //2
是否存在关联性问题或指针不允许以这种方式进行乘法? P.S 我们工作中的用法是
#define SRAM1 0xb0000000+((1048576)-64) //3
或
if((*(OSLongType *)(SRAM1)) == 1)
以这种方式。
答案 0 :(得分:5)
由于您没有提供使用#define
的代码,但这是一个盲目的镜头,但您违反了#define
中有关常量的基本最佳做法之一。
由于#define
被用作盲文替换,如果您不用括号括起计算,则可能会混淆使用您的定义的代码表达式。考虑
#define SEVEN 5+2
然后有人将其用作
printf("thirty-five: %d", SEVEN*5);
这实际上会打印15,因为它将被替换为:
printf("thirty-five: %d", 5+2*5);
因此,为避免出现问题,请始终用括号括起常量定义。为什么最后一个似乎工作在我身后,也许你真的没有用它重新编译?
答案 1 :(得分:2)
我不相信你声称变体(2)会产生你期望的行为,但(1)和(3)会产生彼此不同的行为。此外,如果您确实在使用宏,则按照您的描述:
*(OSLongType *)(SRAM1)= 0;
然后你不会看到(1)和(2)之间的行为有任何差异。
我倾向于认为你实际遇到问题的是
*(OSLongType *)SRAM1= 0;
对于您的变体(1)和(3),这与您的变体(2)有不同的含义。例如,对于变体(1),它扩展为
*(OSLongType *)0xb0000000+((1024*1024)-64)= 0;
。强制转换和间接操作符的优先级高于+
,因此等同于
(*((OSLongType *)0xb0000000)) + ((1024*1024) - 64) = 0;
。这将无法编译,因为赋值的左侧不是左值。变体(3)没有解决这个问题。
然而,对于变体(2),表达式扩展为......
*(OSLongType *)(0xb0000000+((1024*1024)-64))= 0;
......这是完全有效的。地址计算为整数,然后转换为指针,然后解除引用。转换的结果是实现定义的,但代码至少应该编译,它可以做你想要的。
变体(1)和(3)之间唯一可能的区别是为整数常量选择的数据类型。常量1024
肯定具有类型int
,因此表达式1024*1024
也具有类型int
。但是,如果系统的int
只有16位宽,则1024和1024的算术乘积不适合16位整数。在这种情况下,该表达式的结果值是实现定义的,绝对不是1048576.但是,在这种情况下,常量1048676
表示类型long int
的有效值,使得(3)不同来自(1)。
已更新以添加:
我建议一直使用此表单:
#define SRAM1 (0xb0000000+(((uintptr_t)1024*1024)-64))
类型uintptr_t
在stdint.h
中定义,如果您不这样做,则需要包含该类型uintptr_t
。如果你对这种一致性感到满意,你可以向void some_func(int a, int b, int* c){
int cnt = a;
for(;cnt > 0;cnt--){
*c += b;
}
}
void main(){
int a = 5;
int b = 6;
int c = 0;
some_func(a,b,&c);
}
投掷更多的演员阵容,但这些演员阵容不是必需的。