【发布时间】:2018-05-16 00:39:23
【问题描述】:
我有一个包含几个文件的项目: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 之前删除了 cmets:Can you #define a comment in C?
是否有一个巧妙的宏技巧可以隐藏/删除这个赋值,不会将 local_var 放在堆栈上?我觉得三元组有一些可能,但我想不出。
编辑 最小示例代码:
source1.c
int var_name = 0;
source1.h
#ifdef CUST1
extern int var_name;
#else
// clever macro
#endif
source2.c
#include "source1.h"
int main(){
var_name = 1;
return 0;
}
【问题讨论】:
-
"Clever" code is bad code.。不要用另一层混淆来隐藏混淆代码。 修复根本问题。
-
如果
var_name仅是 CUST1,那么您需要#ifdef全部使用它,或者只在大多数地方使用它,而只需 #ifdef 在您不希望它可见的地方。跨度> -
@AndrewHenle 我同意这一点,根本问题是它是在为 CUSTOMER2 编译项目时分配的。 “基本修复”是包装在#ifdef CUST1 宏中使用的逻辑,但不能很好地扩展。有两个以上的客户,现在 var_name 已被外部化,以后可能会在其他地方使用。我同意你的看法,这使事情过于复杂,但事情就是这样。问题是关于隐藏 CUSTOMER2 分配的宏技术。
-
请说明您是否希望将赋值转换为 (a) 无操作、(b) 编译错误或 (c) 运行时错误
-
在 C99 中你可以做
#define var_name (int[]){0}[0]