【问题标题】:Can a macro be used for read-only access to a variable?可以使用宏对变量进行只读访问吗?
【发布时间】:2008-09-26 17:31:27
【问题描述】:

您能否定义一个访问普通变量但以只读方式访问的宏(而不是将其定义为对函数的调用)?比如下面代码中的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. */
}

【问题讨论】:

  • 是否有 const 不适合您的原因?
  • 该值不是恒定的,但只能在有限的地方进行修改。这种宏将允许通过宏进行访问的策略,并有助于最大限度地减少意外修改。它还有助于找出仍然会更改值的遗留代码,这不再是可取的。

标签: c c-preprocessor


【解决方案1】:

好的,我想出了一个:

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

【讨论】:

  • 我也喜欢你的,因为它同样适用于非数字值。
  • 其实可能不会,我觉得三级算子中冒号两边的数据类型一定是一样的。因此,例如,如果 o->value 是一个结构,我认为这是行不通的。你可以把 (o)->value 放在冒号的两边。
【解决方案2】:

如果变量始终为数字,则可行:

#define VALUE(x) (x+0)

或者在你的例子中,

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

【讨论】:

    【解决方案3】:

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

    #define VALUE(x) (0, x)
    

    (不能移植到 C++。)

    【讨论】:

    • 请注意,这不仅适用于数字类型,也适用于structs。 OTOH,在 C++ 中,逗号运算符 确实 产生一个左值,因此它不能以这种方式移植。
    【解决方案4】:

    试试

    #define VALUE(o) (const int)((o)->value)
    

    【讨论】:

      【解决方案5】:

      这是一个谜题还是一项工程任务? 如果这是一项工程任务,那么有更好的方法可以在 C 中获得结构的不透明度。在 this blog article 中,我写了一个足够体面的描述来说明如何在 C 中做到这一点。

      【讨论】:

      • 它看起来很有效,但我正在寻找更快速的东西。我对此有一个特定的应用程序。它不会像托管库那样坚如磐石,但开发时间有限。
      • 与其说是托管/非托管位,不如说是公共不透明结构和 API 与私有开放结构相结合。这是向 API 的客户端隐藏数据的标准 C 技巧。如果你使用 C++,你显然会使用一个类。
      猜你喜欢
      • 2011-05-25
      • 1970-01-01
      • 1970-01-01
      • 2011-07-10
      • 2017-11-11
      • 1970-01-01
      • 2011-07-01
      • 2016-01-14
      • 1970-01-01
      相关资源
      最近更新 更多