2017-03-22 65 views
-3

我已经解决宏(这是一个微控制器,使访问物理地址是OK),打破了这个(有条件定义的长序列后,属性等):比较C宏

#define ADDR_A (*18) 
#define ADDR_B (*30) 
#define ADDR_C (*18) 

我想对它们进行比较,所以我可以优化编译:

#if ADDR_A==ADDR_C 
    return 1; 
#else 
    return 0; 
#endif 

,但我得到“错误:运营商‘*’没有左操作数”,这是有道理的。是否可以比较宏的定义。我有一种预感,我可以将它们转换为字符串来进行比较,但是我没有找到一种方法(就像使用#作为宏参数)。

不,我不想在运行时执行此操作,因为我正在计算周期。

+4

这是无效的C.编译器应该如何知道它是一个地址和该对象的类型?你的问题的其余部分不清楚。你想比较哪些doy,为什么?它闻起来像一个XY-问题。 – Olaf

+0

我完全同意@Olaf。另外,如果表达式只有字面常量(如果要比较两个存储器映射寄存器的地址,那么我所用的所有C编译器都会优化一个普通的'if'语句;而且,由于您使用的是微控制器,因此无论如何您都应该启用优化。换句话说,不需要依赖*预处理器*来优化相关的代码;任何一半体面的C编译器都可以为你做(如果你使用正常的C if语句)。 –

回答

1

你不能在一个#if比较字符串,因为:

  • 你只能使用常量表达式使用#if
  • 串,只能用一个回路或功能
  • 循环AREN”进行比较吨常量表达式
  • 和:

    Constant expressions shall not contain assignment, increment, decrement, function-call, or comma operators, except when they are contained within a subexpression that is not evaluated. (C11, 6.6P3)

我能想到的最好的是分裂的地址和非关联到两个不同的宏,如:

#define ADDR_A (18) 
#define ADDR_B (30) 
#define ADDR_C (18) 
#define GET_A (*ADDR_A) 
#define GET_B (*ADDR_B) 
#define GET_C (*ADDR_C) 

#if ADDR_A == ADDR_B 
return 1 
#else 
return 0 
#endif 

注意检查常量的平等“在运行时”将几乎所有的编译器可被忽略值得它的盐;在this example中,编译器只生成等效的return 1,因为它在编译时知道条件将评估为false;计数周期在这里是一个红鲱鱼,因为这些比较将被消除。我不确定你是如何使用这些宏的(我不能在头脑中构造一个它们在句法上有效的例子),但是我有一种感觉,你的代码会如果您只是让宏包含地址,并且在代码中内联取消引用这些地址,则更容易理解。如果我读你的代码,我会更喜欢:

#define ADDR_A (18) 
#define ADDR_B (30) 
#define ADDR_C (18) 

if (ADDR_A == ADDR_B) 
    return 1 
return 0 
1

如何只将地址放入宏中,并分别输入类型信息?

#define ADDR_A (18) 
#define ADDR_B (30) 
#define ADDR_C (18) 

unsigned uint16_t *A = (uint16_t*)ADDR_A; 
unsigned uint16_t *B = (uint16_t*)ADDR_B; 
unsigned uint16_t *C = (uint16_t*)ADDR_C; 

然后你可以使用你的测试。

另外,跳过预处理器,只是做在C:

unsigned uint16_t *const A = (uint16_t*)18; 
unsigned uint16_t *const B = (uint16_t*)30; 
unsigned uint16_t *const C = (uint16_t*)18; 

int f() 
{ 
    if (A == C) 
     return 1; 
    else 
     return 0; 
} 

除非你有一个非常低质量的编译器,你可以期望它承认A==C作为一个常量表达式和简化代码相应。