Macros C预处理器,用于计算特定于产品的include

Macros C预处理器,用于计算特定于产品的include,macros,c-preprocessor,generic-programming,stringification,Macros,C Preprocessor,Generic Programming,Stringification,我必须维护既有通用组件又有产品特定组件的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

我必须维护既有通用组件又有产品特定组件的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
然后,每当我有一个标题foo.h,其中包含特定于产品的组件时,我都希望使用如下语法

#include "product.h"
#include PRODUCT_SPECIFIC_INCLUDE
其中,
PRODUCT\u SPECIFIC\u INCLUDE
应派生自
文件和
PRODUCT\u NAME
宏,以便将其转换为

#include "Product1/foo.h"
也就是说,特定于产品的头文件与通用文件具有相同的文件名,但位于特定于产品的文件夹中,该文件夹的名称是
product\u name
macro的值

似乎无论我尝试什么,都存在预处理器字符串化问题。我不是第一个想要这样一个结构的人。我错过了什么

更新


以下是我目前为
特定产品\u 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
其次,您试图获取所需的include头名称,但问题出在以下两行:

#define TOKENPASTE(x, y) x ## y
#define PRODUCT_SPECIFIC_INCLUDE TOKENPASTE2(PRODUCT_SPECIFIC, __FILE__)
\uuuu文件\uuuu
此宏将扩展为当前输入文件的名称, 以C字符串常量的形式

TOKENPASTE(特定于产品的,\uuuu文件)
\124;-->
PRODUCT##“foo.h”

产品
永远无法给出有效的令牌。这就是为什么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)

但是我不知道如何避免重复文件名。使用
\uuuuu file\uuuuu
会给出一个字符串,我不知道如何在预处理器中连接字符串(并置字符串是一种解析器功能,而
##
不可用,因为“foo”“bar”不是有效标记的拼写).

我不确定是否可以使用标准C预处理器。您可能需要在生成环境中执行此操作。请显示与
特定于产品的\u INCLUDE
相关的宏,这是我目前为
特定于产品的\u INCLUDE
所用的宏,它不起作用
#定义令牌粘贴(x,y)x##y#定义令牌粘贴2(x,y)标记粘贴(x,y)#定义产品特定的(u包括标记粘贴2(产品特定的)(u文件)
最好将其添加到问题正文中,因为它是重要的部分。这可能是