C 预处理器计算特定产品包括
C Preprocessor to compute product specific include
我必须维护同时具有通用组件和产品特定组件的 C 代码。我想简化我的代码,以便我只有一个通用的 product.h 文件,其结构类似于
#if (PRODUCT_ID == 1)
#define PRODUCT_NAME Product1
#else
#if (PRODUCT_ID == 2)
#define PRODUCT_NAME Product2
#else
#error "Unsupported product id"
#endif
#endif
然后,每当我有一个 header foo.h 具有特定于产品的组件时,我想使用这样的语法
#include "product.h"
#include PRODUCT_SPECIFIC_INCLUDE
其中 PRODUCT_SPECIFIC_INCLUDE
应该从 __FILE__
和 PRODUCT_NAME
宏以这样一种方式派生,它会转换为
#include "Product1/foo.h"
也就是说,特定于产品的 header 文件与通用文件具有相同的文件名,但位于特定于产品的文件夹中,其名称是 PRODUCT_NAME
宏的值。
似乎无论我尝试什么都存在预处理器字符串化问题。我不可能是第一个想要这种结构的人。我错过了什么?
更新
这是我目前为 PRODUCT_SPECIFIC_INCLUDE
准备的,但没有用
#define TOKENPASTE(x, y) x ## y
#define TOKENPASTE2(x, y) TOKENPASTE(x, y)
#define PRODUCT_SPECIFIC_INCLUDE TOKENPASTE2(PRODUCT_SPECIFIC, __FILE__)
第一个代码可以简化为:
#if (PRODUCT_ID == 1)
#define PRODUCT_NAME Product1
#elif (PRODUCT_ID == 2)
#define PRODUCT_NAME Product2
#else
#error "Unsupported product id"
#endif
其次,您正在尝试获取所需的包含 header 名称,但问题出在这两行中:
#define TOKENPASTE(x, y) x ## y
#define PRODUCT_SPECIFIC_INCLUDE TOKENPASTE2(PRODUCT_SPECIFIC, __FILE__)
__FILE__
: This macro expands to the name of the current input file,
in the form of a C string constant
TOKENPASTE(PRODUCT_SPECIFIC, __FILE__)
|--> product ## "foo.h"
product
和 "
永远无法给出有效的令牌。这就是 CPP 给你错误的原因。您需要的是将 文件名写成纯文本 以便您可以将它与其他宏组合。
你可以这样做:
#define TOKENPASTE(x) #x
#define TOKENPASTE2(x) TOKENPASTE(x)
#define PRODUCT_SPECIFIC_INCLUDE TOKENPASTE2(PRODUCT_SPECIFIC/foo.h)
#include PRODUCT_SPECIFIC_INCLUDE
你可以这样做
#define STR2(F) #F
#define STR(F) STR2(F)
#define MAKE_PRODUCT_INCLUDE(FILE) STR(PRODUCT_SPECIFIC/FILE)
#include MAKE_PRODUCT_INCLUDE(foo.h)
但我不知道如何避免重复文件名。使用 __FILE__
给出一个字符串,我不知道如何在预处理器中连接字符串(连接并列字符串的事实是一个解析器功能,##
不能用于 "foo""bar" 不是有效标记的拼写)。
我必须维护同时具有通用组件和产品特定组件的 C 代码。我想简化我的代码,以便我只有一个通用的 product.h 文件,其结构类似于
#if (PRODUCT_ID == 1)
#define PRODUCT_NAME Product1
#else
#if (PRODUCT_ID == 2)
#define PRODUCT_NAME Product2
#else
#error "Unsupported product id"
#endif
#endif
然后,每当我有一个 header foo.h 具有特定于产品的组件时,我想使用这样的语法
#include "product.h"
#include PRODUCT_SPECIFIC_INCLUDE
其中 PRODUCT_SPECIFIC_INCLUDE
应该从 __FILE__
和 PRODUCT_NAME
宏以这样一种方式派生,它会转换为
#include "Product1/foo.h"
也就是说,特定于产品的 header 文件与通用文件具有相同的文件名,但位于特定于产品的文件夹中,其名称是 PRODUCT_NAME
宏的值。
似乎无论我尝试什么都存在预处理器字符串化问题。我不可能是第一个想要这种结构的人。我错过了什么?
更新
这是我目前为 PRODUCT_SPECIFIC_INCLUDE
准备的,但没有用
#define TOKENPASTE(x, y) x ## y
#define TOKENPASTE2(x, y) TOKENPASTE(x, y)
#define PRODUCT_SPECIFIC_INCLUDE TOKENPASTE2(PRODUCT_SPECIFIC, __FILE__)
第一个代码可以简化为:
#if (PRODUCT_ID == 1)
#define PRODUCT_NAME Product1
#elif (PRODUCT_ID == 2)
#define PRODUCT_NAME Product2
#else
#error "Unsupported product id"
#endif
其次,您正在尝试获取所需的包含 header 名称,但问题出在这两行中:
#define TOKENPASTE(x, y) x ## y
#define PRODUCT_SPECIFIC_INCLUDE TOKENPASTE2(PRODUCT_SPECIFIC, __FILE__)
__FILE__
: This macro expands to the name of the current input file, in the form of a C string constant
TOKENPASTE(PRODUCT_SPECIFIC, __FILE__)
|--> product ## "foo.h"
product
和 "
永远无法给出有效的令牌。这就是 CPP 给你错误的原因。您需要的是将 文件名写成纯文本 以便您可以将它与其他宏组合。
你可以这样做:
#define TOKENPASTE(x) #x
#define TOKENPASTE2(x) TOKENPASTE(x)
#define PRODUCT_SPECIFIC_INCLUDE TOKENPASTE2(PRODUCT_SPECIFIC/foo.h)
#include PRODUCT_SPECIFIC_INCLUDE
你可以这样做
#define STR2(F) #F
#define STR(F) STR2(F)
#define MAKE_PRODUCT_INCLUDE(FILE) STR(PRODUCT_SPECIFIC/FILE)
#include MAKE_PRODUCT_INCLUDE(foo.h)
但我不知道如何避免重复文件名。使用 __FILE__
给出一个字符串,我不知道如何在预处理器中连接字符串(连接并列字符串的事实是一个解析器功能,##
不能用于 "foo""bar" 不是有效标记的拼写)。