我有一个包含少量文件的项目:source1.c source2.c source1.h source2.h。现在source1.c声明了一些变量,source1.h遍历它们(使用条件构建宏)。然后,source2.c将通过为它们分配值来使用extern变量。
问题是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时,它永远不会声明/ outta作用域。
我不想将var_name用于CUST2,它是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之前会删除注释: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;
}
答案 0 :(得分:1)
没有直接隐藏任务的方法,但有一些替代方案:
您可以使用其他宏:
#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());
}
您可以测试是否在source2.c中定义了CUST1
:
/* 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());
}
由于您不希望通过将每个分配包装在#ifdef CUST1 ... #endif
中来重复代码,您可以使用该函数或宏。请记住,选项#1还会将宏SET_VAR_TO
公开给#include
的source1.h文件,而不仅仅是source2.c。
答案 1 :(得分:1)
extern int varname;
#define varname __attribute__((unused)) int varname
int square(int num) {
varname = 1;
return num * num;
}
除了-O0
之外,它可以在任何优化级别工作答案 2 :(得分:1)
如果var_name
未定义source2.c
时无法访问CUST1
中访问#include <stdlib.h>
#define var_name (*(abort(), (type *)0))
的代码(如您所说),那么您可以这样定义:
func scrollViewWillBeginZooming(_ scrollView: UIScrollView, with view: UIView?) {
scrollView.pinchGestureRecognizer?.isEnabled = false
}
这在语法上可以作为正确类型的左值(或右值),但如果程序实际执行过,它将中止该程序。