2015-12-09 10 views
-2

我在一个项目中,我们有大量内存作为工作的#define 如我得到的结果不同,而使用的#define

#define SRAM1  0xb0000000+((1024*1024)-64) //1 

如果我使用上面的#define 如果我得到了一个错误我改变这个

#define SRAM1  (0xb0000000+((1024*1024)-64)) //2 

它的工作原理。 即使这个工程

#define SRAM1  0xb0000000+((1048576)-64)  //3 

是否与关联或指针乘法问题这样是不允许的? P.S 使用在我们的工作是

  if((*(OSLongType *)(SRAM1)) == 1) 

  *(OSLongType *)(SRAM1)= 0; 
这样

+0

你得到第一个错误是什么错误? – Magisch

+0

系统崩溃。 –

+4

请添加实际使用此宏的代码 – Shloim

回答

5

由于您没有提供使用#define的代码,但您违反了有关#define中的常量的基本最佳做法之一,所以这有些盲目。

由于#define s作为盲文替换应用,如果您不用括号括起计算,那么您可能会混淆使用您的定义的代码表达式。考虑

#define SEVEN 5+2 

,然后有人用它作为

printf("thirty-five: %d", SEVEN*5); 

这实际上将打印15,因为它会被替换为:

printf("thirty-five: %d", 5+2*5); 

因此,为了避免问题始终围绕你的不变用括号定义。为什么最后一个似乎工作在我身后,也许你没有真正重新编译它?

+0

这种代码不能用于两个以上的文件。我检查了是否存在这样的问题,但是无论在哪里,#define都被隐藏起来,没有显示任何乘法。 –

+0

我在编译和检查二进制文件的构建时间之前闪烁。 –

+0

Nitpick:它实际上会打印15;) – szczurcio

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,但他们没有必要。

+0

我不得不在另一个答案下删除我之前的评论,其中说“但OP的代码失败*带圆括号”,因为这个问题措辞不佳,我认为有一个完整的在他的第三条线上失踪了。但我同意你的看法,如果第一个例子不行,他的最后一个例子如何工作? –

+0

我会跟我说话。向他展示代码并要求澄清。我还将提供我正在使用的更简单的代码版本。这是一个大项目,给上下文并不那么容易,但我可以确保我编写的代码片段与我所做的任何评论完全正确。 –

相关问题