【问题标题】:use of #define to create a dummy record compatible with C89 std使用 #define 创建与 C89 std 兼容的虚拟记录
【发布时间】:2018-07-10 13:53:15
【问题描述】:

如何根据 C89 标准使用 #define 创建虚拟记录? 我试过了:

    typedef struct foo{int a; int b;}foo;
    #define DUMMY (foo) {.a=0, .b=0}

它运行良好,但是当我使用 -std=c89 编译时会出现很多警告。警告说这种东西只与 C99 标准兼容。谢谢大家!!

【问题讨论】:

  • 你不能。 C89 既不支持复合文字也不支持指定的初始值设定项。
  • @Eugene Sh.非常感谢!
  • 会创建一个命名对象,如foo MyDummy = { 0, 0 };,然后定义宏来引用它,#define DUMMY MyDummy,是否符合您的目的? (或者,就此而言,只需定义 foo DUMMY = { 0, 0 }; 而根本不使用宏。)
  • @Eric Postpischil,非常感谢!是的,两种解决方案都适合!第二种方案是否兼容 C89?

标签: c macros c89


【解决方案1】:

在 C89 中,可以在函数中使用的聚合(结构/联合)类型的唯一值是命名对象、函数返回值、取消引用的指针或其他聚合的成员。而 C 包含一个构造,该构造定义了一个用常量数据初始化的字符数组,并将其作为左值 [i.e.字符串文字],没有任何其他类型的等价物。

如前所述,如果您可以创建命名静态对象,则可以使用:

static struct foo const doubleZero = {0,0};
#define DUMMY doubleZero

宏的使用将与使用#ifdef DUMMY 来确定它是否已被定义的代码兼容。

如果您需要根据可能变化的参数创建对象的能力,您可以使用类似:

struct fooWrapper { struct foo dat[1]; };
struct fooWrapper makeFoo(int a, int b)
{ struct fooWrapper result; result[0].a=a; result[0].b=b; return result; }
#define MAKEFOO(a,b) (*(fooWrapper((a),(b)).dat))

这将允许代码将 MAKEFOO 的结果视为左值,从而允许例如

memcpy(whatever, &MAKEFOO(3,5), sizeof (struct foo));

返回的包装对象的生命周期不会像 C 复合字面量那样长,但对于大多数 C 复合字面量就足够的用途来说应该足够了。

【讨论】:

    猜你喜欢
    • 2019-04-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-13
    • 2021-02-06
    • 2021-04-26
    • 2017-05-23
    • 1970-01-01
    相关资源
    最近更新 更多