在C中运行时更改宏

时间:2023-01-28 12:29:57

I have a macro defined. But I need to change this value at run time depending on a condition. How can I implement this?

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

5 个解决方案

#1


25  

Macros are replaced by the preprocessor by their value before your source file even compiles. There is no way you'd be able to change the value of the macro at runtime.

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

If you could explain a little more about the goal you are trying to accomplish undoubtedly there is another way of solving your problem that doesn't include macros.

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

#2


23  

You can't change the macro itself, i.e. what it expands to, but potentially you can change the value of an expression involving the macro. For a very silly example:

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

#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);
}

So the answer to your question depends on what kind of effect you want your change to have on code that uses the macro.

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

Of course 5 is a compile-time constant, while foo isn't, so this doesn't work if you planned to use CHANGEABLE_VALUE as a case label or whatever.

当然5是编译时常量,而foo不是,所以如果你计划使用CHANGEABLE_VALUE作为案例标签或其他什么,这不起作用。

Remember there are two (actually more) stages of translation of C source. In the first (of the two we care about), macros are expanded. Once all that is done, the program is "syntactically and semantically analyzed", as 5.1.1.2/2 puts it. These two steps are often referred to as "preprocessing" and "compilation" (although ambiguously, the entire process of translation is also often referred to as "compilation"). They may even be implemented by separate programs, with the "compiler" running the "preprocessor" as required, before doing anything else. So runtime is way, way too late to try to go back and change what a macro expands to.

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

#3


12  

You can't. Macros are expanded by the Preprocessor, which happens even before the code is compiled. It is a purely textual replacement.

你不能。宏由预处理器扩展,甚至在编译代码之前就会发生。它纯粹是文本的替代品。

If you need to change something at runtime, just replace your macro with a real function call.

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

#4


7  

You can't.

你不能。

As a macro is resolved by the preprocessor before the compilation itself, its content is directly copied where you use it.

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

You can still use parameters to insert a conditional statement depending on what you want, or use a call-scope accessible variable.

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

If you want to change a single value, better use global scope variable, even if such behavior is discouraged. (as the intensive use of macro)

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

#5


4  

Depending on what you want to do, you might do it several ways.

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

Global variable instead of macro

全局变量而不是宏

// 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

Condition you can toggle

您可以切换的条件

// 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

Condition that's locally and dynamically evaluated

本地和动态评估的条件

// 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

In that last one the CONDITION will be evaluated as if its code were in your local scope, so you can use local variables and/or parameters in it, but you can also use global variables if you want.

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

#1


25  

Macros are replaced by the preprocessor by their value before your source file even compiles. There is no way you'd be able to change the value of the macro at runtime.

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

If you could explain a little more about the goal you are trying to accomplish undoubtedly there is another way of solving your problem that doesn't include macros.

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

#2


23  

You can't change the macro itself, i.e. what it expands to, but potentially you can change the value of an expression involving the macro. For a very silly example:

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

#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);
}

So the answer to your question depends on what kind of effect you want your change to have on code that uses the macro.

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

Of course 5 is a compile-time constant, while foo isn't, so this doesn't work if you planned to use CHANGEABLE_VALUE as a case label or whatever.

当然5是编译时常量,而foo不是,所以如果你计划使用CHANGEABLE_VALUE作为案例标签或其他什么,这不起作用。

Remember there are two (actually more) stages of translation of C source. In the first (of the two we care about), macros are expanded. Once all that is done, the program is "syntactically and semantically analyzed", as 5.1.1.2/2 puts it. These two steps are often referred to as "preprocessing" and "compilation" (although ambiguously, the entire process of translation is also often referred to as "compilation"). They may even be implemented by separate programs, with the "compiler" running the "preprocessor" as required, before doing anything else. So runtime is way, way too late to try to go back and change what a macro expands to.

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

#3


12  

You can't. Macros are expanded by the Preprocessor, which happens even before the code is compiled. It is a purely textual replacement.

你不能。宏由预处理器扩展,甚至在编译代码之前就会发生。它纯粹是文本的替代品。

If you need to change something at runtime, just replace your macro with a real function call.

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

#4


7  

You can't.

你不能。

As a macro is resolved by the preprocessor before the compilation itself, its content is directly copied where you use it.

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

You can still use parameters to insert a conditional statement depending on what you want, or use a call-scope accessible variable.

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

If you want to change a single value, better use global scope variable, even if such behavior is discouraged. (as the intensive use of macro)

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

#5


4  

Depending on what you want to do, you might do it several ways.

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

Global variable instead of macro

全局变量而不是宏

// 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

Condition you can toggle

您可以切换的条件

// 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

Condition that's locally and dynamically evaluated

本地和动态评估的条件

// 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

In that last one the CONDITION will be evaluated as if its code were in your local scope, so you can use local variables and/or parameters in it, but you can also use global variables if you want.

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