c - 隐藏赋值的C宏技巧?
问题描述
我有一个包含少量文件的项目:source1.c source2.c source1.h source2.h。现在 source1.c 声明了一些变量,并且 source1.h 将它们外部化(使用条件构建宏)。source2.c 然后将通过为外部变量赋值来使用它们。
问题是 source1.h 具有以下内容:
#ifdef CUST1
extern type var_name;
#else
// Need to extern something or use a clever macro here but i dont like these below
//#define var_name int x (requires top of scope block usage)
//#define var_name // (doesnt compile)
//#define var_name -1 (simply doesnt compile)
//#define var_name 1= (This seems like it would reduce to unused 1==1; but doesnt work)
#endif
我的构建适用于 CUST1,但不适用于 CUST2,因为在 source2.c 中引用 var_name 时从未声明/超出范围。
我不想对 CUST2 使用 var_name,它是 source2.c 中无法访问的代码。这是我的问题,我如何使用宏来#define var_name 以便赋值“消失”或什么都不做?
我可以“#define var_name int x”。这会将 int x 放在 source2.c 函数中的堆栈上,并在 source2.c 中分配值,但如果它在除作用域块顶部之外的任何地方被引用,我的旧(C89?)编译器将出错。
例如,如果 source2.c 曾经有以下内容,它将无法编译:
unsigned short local_var = 0;
local_var = 1; //or someother value
var_name = local_var * 2;
我可以使用相同的 #ifdef CUST1 宏将逻辑包装在 source2.c 中,但这似乎也不太好。
如果 var_name 只是被比较,它不会那么糟糕,因为我可以只使用 #define var_name -1 或者会失败所有比较/切换的东西。问题是 -1 = temp_var; 无法编译,因为 -1 不能是左值。
类似地,我不能“#define var_name //”,因为在根据以下内容替换 marcos 之前删除了注释:你能在 C 中#define a comment 吗?
是否有一个巧妙的宏技巧可以隐藏/删除此分配,不会将 local_var 放在堆栈上?我觉得三元组有一些可能,但我想不出。
编辑 最小示例代码:
源1.c
int var_name = 0;
源1.h
#ifdef CUST1
extern int var_name;
#else
// clever macro
#endif
源代码2.c
#include "source1.h"
int main(){
var_name = 1;
return 0;
}
解决方案
没有像您建议的那样直接隐藏作业的方法,但有一些替代方法:
您可以使用另一个宏:
#ifdef CUST1 extern type var_name; /* Do the real assignment */ #define SET_VAR_TO(val) do{ var_name = (val); } while(0) #else /* Just evaluate for the side-effects */ #define SET_VAR_TO(val) do { val; } while(0) #endif
然后在 source2.c 中将所有分配替换
var_name
为SET_VAR_TO(value)
:int foo(void) { /* Replace var_name = bar(); * With: */ SET_VAR_TO(bar()); }
您可以测试是否
CUST1
也在 source2.c 中定义:/* in source2.c */ int foo(void) { #ifdef CUST1 var_name = bar(); #endif }
在这种情况下,您甚至可以将分配包装到仅在源文件中定义的真实函数:
/* in source2.c */ int set_var_to(type value) { #ifdef CUST1 var_name = value; #endif } int foo(void) { /* Replace var_name = bar(); * With: */ set_var_to(bar()); }
由于您不希望通过将每个分配包装在 an 中来重复代码,因此#ifdef CUST1 ... #endif
您可以使用函数或宏。请记住,选项 #1 也会将宏暴露SET_VAR_TO
给任何#include
source1.h 文件,而不仅仅是 source2.c。
推荐阅读
- javascript - 如何在两天之间显示表格行?
- powershell - 读取性能计数器的问题(阵列问题)
- python - 删除python中的列后如何自动更改excel中的相对单元格公式?
- javascript - Promise 已创建但未在 knex 中返回
- sparql - SPARQL 三重过滤器不完全匹配
- configserver - Spring Boot Config Server - 总是返回旧值
- reactjs - 单击清除按钮,从数据表中删除数据
- javascript - 如何为 wtform 烧瓶的输入字段的一部分着色
- postgresql - Azure Postgresql 服务器中的日志信息
- android - Three.js在Android微信上使用VideoTexture