【问题标题】:c macro, array definition as parameterc宏,数组定义作为参数
【发布时间】:2014-09-14 20:28:29
【问题描述】:

我有这个方法

foo_l(int *array, size_t l)
{
    /*
    code
    */
}

我写了这个宏

#define foo(X) foo_l(X,sizeof(X)/sizeof(int))

所以我可以如下使用它们

int main()
{
    int a[]={1,2,3};
    foo(a);
    return 0;
}

并且避免每次都写入数组的长度。


我的问题是,我可以扩展我的宏以便它可以处理类似的事情

foo_l((int[]){1,2,3}, 3);

在函数参数字段中声明了一个数组?

因为foo((int[]){1,2,3}) 不起作用!我认为问题在于宏将(int[]){1,2,3} 视为参数列表而不是唯一参数。有什么想法吗?

附:我对宏观世界很陌生,我通常使用 c99。

【问题讨论】:

    标签: c arrays macros


    【解决方案1】:

    当被传递给预处理器时,宏 foo((int[]){1,2,3}) 失败,因为预处理器认为它提供了 3 个参数而不是 1 个:

    foo((int[]){1,2,3});
    // is believed to be:
    // Start of macro: foo(
    // Parameter 1:    (int[]){1, 
    // Parameter 2:    2, 
    // Parameter 3:    3}
    // End of macro:   );
    

    所以它不会编译并给出如下内容:

    a.c: In function ‘main’:
    a.c:15:23: error: macro "foo" passed 3 arguments, but takes just 1
         foo((int[]){1,2,3});
    

    添加另一对括号即可解决问题:

    // This shall work
    foo(((int[]){1,2,3}));
    

    已编辑:

    是的,我想这可能不是一个好的设计,因为像普通程序员这样的人可能很可能将指针而不是数组类型传递给您的宏 foo,并且正如 @DwayneTowell 指出的那样它会失败。 请注意这一点。 :)

    【讨论】:

      【解决方案2】:

      您的建议不是一个好主意,因为在以下情况下它会失败:

      int a[] = {1,2,3,4};
      int *b = a;
      foo(b);        // becomes foo_l(b,sizeof(b)/(sizeof(int));
                     // probably becomes foo_l(b,1)
      

      通常,如果第一个参数是指向数组的指针而不是数组本身,则 size 参数会出错。通常,当 sizeof(int *)==sizeof(int) 时,表达式的计算结果为 1,这是很常见但标准要求的。

      【讨论】:

      • 我同意。此外,它不适用于在编译时不知道其大小的数组(分配的数组)。不过,可以仅将其用于编译时数组。
      • sizeof 会失败,因为您传递的是指针而不是数组类型。
      • sizeof(int *) 不会失败,它返回一个指针的大小,现在通常是 4 或 8 个字节。
      • @DwayneTowell 我明白了,但是 OP 想通过sizeof(X)/sizeof(int) 计算数组长度,不是吗?这就是我所说的“失败”。
      • @starrify,很公平,我同意从 stict OP 问题的角度来看,我的“答案”可能会被视为离题,但总的来说这是一个坏主意,我觉得有人需要以“前面有龙”的方式回答它,而不是盲目地回答所提出的确切问题。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-01-15
      • 2015-07-12
      • 2012-09-07
      • 1970-01-01
      • 2013-12-28
      • 2017-01-14
      相关资源
      最近更新 更多