如何测试两个#defines是否与C预处理器相同

时间:2014-07-08 14:05:31

标签: c c-preprocessor

我有一个C程序,它具有特定于平台的定义,用于访问低级硬件。在某些平台上,两个宏指向同一个变量,而另一个平台则不同:

 //Platform_One.h
 #define FOO_PORT   (io.portA)
 #define BAR_PORT   (io.portB)

 //Platform_Two.h
 #define FOO_PORT   (io.portC)
 #define BAR_PORT   (io.portC)  //same

根据#defines是否相同,我有一些不同的初始化代码。从概念上讲,我喜欢这样的代码:

 callback_struct_t callbacks[] = {
 #if FOO_PORT == BAR_PORT           //unfortunately invalid
     {&FOO_PORT, handle_foo_bar_func},
 #else
     {&FOO_PORT, handle_foo_func},
     {&BAR_PORT, handle_bar_func},
 #endif          
      {0,0}
 };

如果两个任意宏具有相同的定义,是否有可靠的方法在编译时进行测试?

3 个答案:

答案 0 :(得分:3)

您无法将预处理器宏与字符串进行比较。一种可能性是将硬件端口地址(例如,通过特定于平台的标头中的另一个宏)放入#define,然后比较地址。

但是,最简单的方法可能是在实际代码中进行地址比较,例如:

if (&FOO_PORT == &BAR_PORT) {
    // populate callbacks with handle_foo_bar_func
} else {
    // populate callbacks with handle_foo_func and handle_bar_func
}

虽然未在预处理器中完成,但编译器可能能够优化掉未使用的分支,因为硬件地址可能是编译时常量。

答案 1 :(得分:2)

使用gnu c处理器,可以使用字符串化来完成:https://gcc.gnu.org/onlinedocs/cpp/Stringification.html#Stringification

你可以这样做:

#include <stdio.h>
#include <string.h>

#define FOO_PORT   (io.portA)
#define BAR_PORT   (io.portB)

//#define FOO_PORT   (io.portC)
//#define BAR_PORT   (io.portC)

#define XMACRO_TEST(macro_a, macro_b) MACRO_TEST(macro_a, macro_b)

#define MACRO_TEST(macro_a, macro_b) \
    if(strcmp((#macro_a),(#macro_b)) == 0) { \
        printf(#macro_a" == "#macro_b"\n"); \
    } else { \
        printf(#macro_a" != "#macro_b"\n"); \
    } \

int main(int argc, char *argv[])
{
    XMACRO_TEST(FOO_PORT, BAR_PORT)

    return 0;
}

答案 2 :(得分:1)

您可以将评估的宏与整数进行比较。 我的理解是你有三个选择:

  • 更改宏逻辑
  • 使用端口号宏的数值(它们是物理地址吗?)
  • 使用c代码填充回调结构作为评论之一。

最后一个选项似乎是最有利的。无论如何,在使用const的情况下,计算将在大多数编译器的适应时间进行。