在C中运行时更改宏

时间:2011-09-27 16:56:35

标签: c c-preprocessor

我定义了一个宏。但我需要在运行时根据条件更改此值。 我该如何实现呢?

5 个答案:

答案 0 :(得分:29)

在源文件甚至编译之前,宏会被预处理器替换为它们的值。您无法在运行时更改宏的值。

如果你能解释一下你正在努力实现的目标,毫无疑问还有另一种方法来解决你的问题,不包括宏。

答案 1 :(得分:25)

您无法更改宏本身,即它扩展到的内容,但您可以更改涉及宏的表达式的值。对于一个非常愚蠢的例子:

#include <stdio.h>

#define UNCHANGEABLE_VALUE 5
#define CHANGEABLE_VALUE foo

int foo = 5;

int main() {
    printf("%d %d\n", UNCHANGEABLE_VALUE, CHANGEABLE_VALUE);
    CHANGEABLE_VALUE = 10;
    printf("%d %d\n", UNCHANGEABLE_VALUE, CHANGEABLE_VALUE);
}

因此,您的问题的答案取决于您希望更改对使用宏的代码产生何种影响。

当然5是编译时常量,而foo则不是,因此如果您计划将CHANGEABLE_VALUE用作case,则无效标签或其他什么。

请记住,C源的翻译有两个(实际上更多)阶段。在第一个(我们关心的两个)中,扩展了宏。完成所有操作后,程序将进行“语法和语义分析”,如5.1.1.2/2所述。这两个步骤通常被称为“预处理”和“编译”(虽然含糊不清,但整个翻译过程通常也称为“编译”)。它们甚至可以由单独的程序实现,“编译器”在执行任何其他操作之前根据需要运行“预处理器”。因此,运行时太晚,无法尝试返回并更改宏扩展到的内容。

答案 2 :(得分:13)

你做不到。宏由Preprocessor扩展,甚至在编译代码之前就会发生。它纯粹是文本的替代品。

如果您需要在运行时更改某些内容,只需使用实际函数调用替换宏。

答案 3 :(得分:7)

你不能。

由于宏在编译本身之前由预处理器解析,因此将其内容直接复制到您使用它的位置。

您仍然可以根据需要使用参数插入条件语句,或使用调用范围可访问变量。

如果要更改单个值,请更好地使用全局范围变量,即使不鼓励这样做。 (作为宏观的密集使用)

答案 4 :(得分:4)

根据您的目的,您可以采取多种方式。

全局变量而不是宏

// someincludefile.h
extern static int foo;

// someincludefile.c
static int foo = 5;

// someotherfile.c
#include "someincludefile.h"
printf("%d\n", foo); // >> 5
foo = -5;
printf("%d\n", foo); // >> -5

您可以切换的条件

// someincludefile.h
extern static int condition;
#define FOO1 (5)
#define FOO2 (-5)
#define FOO (condition ? (FOO1) : (FOO2))

// someincludefile.c
static int condition = 1;

// someotherfile.c
#include "someincludefile.h"
printf("%d\n", FOO); // >> 5
condition = 0;
printf("%d\n", FOO); // >> -5

本地和动态评估的条件

// someincludefile.h
#define CONDITION (bar >= 0)
#define FOO1 (5)
#define FOO2 (-5)
#define FOO ((CONDITION) ? (FOO1) : (FOO2))

// someotherfile.c
#include "someincludefile.h"
int bar = 1;
printf("%d\n", FOO); // >> 5
bar = -1;
printf("%d\n", FOO); // >> -5

在最后一个中,CONDITION将被评估为其代码在本地范围内,因此您可以在其中使用局部变量和/或参数,但如果需要,您也可以使用全局变量。