Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/61.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 宏能否用于对变量的只读访问?_C_C Preprocessor - Fatal编程技术网

C 宏能否用于对变量的只读访问?

C 宏能否用于对变量的只读访问?,c,c-preprocessor,C,C Preprocessor,是否可以定义一个访问普通变量的宏,但它是只读的(而不是定义为函数调用)?例如,以下代码中的VALUE宏是否可以定义为dostuff()函数导致编译错误 struct myobj { int value; } /* This macro does not satisfy the read-only requirement */ #define VALUE(o) (o)->value /* This macro uses a function, unfortunately */ int

是否可以定义一个访问普通变量的宏,但它是只读的(而不是定义为函数调用)?例如,以下代码中的VALUE宏是否可以定义为dostuff()函数导致编译错误

struct myobj {
  int value;
}

/* This macro does not satisfy the read-only requirement */
#define VALUE(o) (o)->value

/* This macro uses a function, unfortunately */
int getvalue(struct myobj *o) { return o->value; }
#define VALUE(o) getvalue(o)

void dostuff(struct myobj *foo) {
   printf("The value of foo is %d.\n", VALUE(foo)); /* OK */
   VALUE(foo) = 1; /* We want a compile error here */
   foo->value = 1; /* This is ok. */
}

如果变量始终为数字,则此操作有效:

#define VALUE(x) (x+0)
或者在你的例子中

#define VALUE(x) (x->value+0)
试一试


好的,我想到了一个:

#define VALUE(o) (1 ? (o)->value : 0)

这是一个难题还是一项工程任务?
如果这是一项工程任务,那么有更好的方法来获得C中结构的不透明度。在年,我写了一篇关于如何在C中做到这一点的相当不错的描述。

参见C标准(C99和C1x)中的§6.5.17:“逗号运算符不会产生左值。”

#define VALUE(x) (0, x)

(不可移植到C++)

是否有一个原因const将不为您工作?值不是常数,而是应该只在有限的地方修改。这种宏允许通过宏进行访问,并有助于最大限度地减少意外修改。它还将有助于找出仍然改变值的遗留代码,这不再是理想的。我也喜欢你的代码,因为它同样容易处理非数值。实际上可能不是,我认为冒号两侧的数据类型在第三运算符中必须相同。因此,如果o->value是一个结构,例如,我认为这不起作用。你可以在冒号的两边都加上(o)->值。它看起来很有效,但我想找一个更快更脏的。我有一个具体的应用在这方面的想法。它不会像托管库那样坚如磐石,但开发时间有限。与其说它是托管/非托管的,不如说它是公共不透明结构和API与私有开放结构的结合。这是将数据隐藏到API客户端的标准C技巧。如果你使用C++,你显然会使用类。注意这不仅仅是数字类型,而且是用于<代码>结构> <代码> s。OTHH,在C++中逗号运算符确实产生一个LValk,因此它不是可移植的。
#define VALUE(x) (0, x)