使用定义的常量(来自 Makefile)在 C 中形成变量名称的一部分

using defined constant (from Makefile) to form a part of a variable name in C

本文关键字:变量名 一部分 定义 常量 Makefile 来自      更新时间:2023-10-16

是否可以使用定义的常量来构成 C 中变量名的一部分?常量由生成文件定义。(实际上我想通过如下所示的 make 参数传递它)
例如,我想定义一个数字NUM并使用它声明一个变量。

#define NUM 5
/* I want to declare as below
int var5 
using defined constant `NUM` above
*/

我试过了

int var ## NUM;

但是##串联仅用于预处理宏操作,不起作用.
实际上,常量NUM是从 mycase.
中的 Makefile(通过 CFLAGS += -DNUM=5)传入的我该怎么做?

ADD1

根据Shachar Shemesh下面的回答,我尝试了这个。

=== 测试.c

#include <stdio.h>
#define compound_id(name1, name2) name1##name2
int compound_id(mynum, NUM);
main()
{
mynum5 = 5;
printf("NUM = %dn", NUM);
printf("mynum5 = %dn", mynum5);

== 生成文件

ifeq ($(NUM),5)
CFLAGS+=-DNUM=$(NUM)
endif

== 命令

make test NUM=5

我得到以下结果:

ckim@stph45:/tmp] make test NUM=5
cc -DNUM=5    test.c   -o test
test.c: In function 'main':
test.c:8: error: 'mynum5' undeclared (first use in this function)
test.c:8: error: (Each undeclared identifier is reported only once
test.c:8: error: for each function it appears in.)
make: *** [test] Error 1

怎么了?

添加 2

:我也试过这个,(没有制作文件,只是运行make test
=== 测试.c

#include <stdio.h>
#define NUM 5
#define mynum(X) (int mynum##X;)
mynum(NUM)
main()
{
printf("NUM = %dn", NUM);
mynum5 = 5;
printf("mynum5 = %dn", mynum5);
}

并得到此错误:

ckim@stph45:/tmp] make test
cc     test.c   -o test
test.c:5: error: expected identifier or '(' before 'int'
make: *** [test] Error 1

您需要使用宏来使用预处理器的串联。但是,为了确保NUM也经过预处理,必须使用两个级别的宏,例如:

#define CONCAT_IMPL(LHS, RHS) LHS ## RHS
#define CONCAT(LHS, RHS) CONCAT_IMPL(LHS, RHS)

请参阅参数预扫描。

您可以使用

的一个选项是多级宏扩展。 试试这个:

#include <stdio.h>
/* This emulates the constant that comes from your makefile. */
#define NUM 5
/* This allows VAR2() to be called with the value of NUM (5)
   instead of just the string "NUM". */
#define VAR(x) VAR2(x)
/* This actually concatenates 'var' and '5' to be 'var5'. */
#define VAR2(x) var##x
/* This allows you to stringify your variable name.
   Again, we're using multilevel macro expansion so we get the
   desired output string "var5" and not "VAR(NUM)". */
#define MACRO_STRINGIFY(x) STRINGIFY(x)
#define STRINGIFY(x) #x

int main(int argc, char **argv)
{
    /* Declare your variable */
    int VAR(NUM);
    /* Assign a value to your variable */
    VAR(NUM) = 7;
    /* Print your variable name and its value */
    printf(MACRO_STRINGIFY(VAR(NUM)) " = %dn", VAR(NUM));
    return 0;
}

下面是输出:

var5 = 7

如果您不明白为什么这是输出,以下是预处理后(即所有宏扩展都已完成)但在编译之前main()的外观:

int main(int argc, char **argv)
{
    int var5;
    var5 = 7;
    printf("var5" " = %dn", var5);
    return 0;
}

您可以通过预处理源文件来准确查看宏会变成什么。 例如,如果您正在使用gcc并且源文件source.c则可以像这样对其进行预处理,结果存储在source.i中:

# gcc -E source.c -o source.i
#define compound_id(name1, name2) name1##name2
int compound_id(var, NUM);