使用#defines时,我得到的结果不同

时间:2015-12-09 14:44:37

标签: c

我正在一个项目中工作,我们有很多内存作为#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)

以这种方式。

2 个答案:

答案 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_tstdint.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); } 投掷更多的演员阵容,但这些演员阵容不是必需的。