C99 使得基本上可以在任何地方将数组定义为复合文字。
例如,给定一个sumf()
接受数组float
作为输入的普通函数,我们期望原型为:
float sumf(const float* arrayf, size_t size);
然后可以这样使用:
float total = sumf( (const float[]){ f1, f2, f3 }, 3 );
这很方便,因为不需要事先声明变量。语法有点难看,但这可以隐藏在宏后面。
但是,请注意最后的3
. 这是数组的大小。它是必需的,以便sumf()
知道在哪里停止。但是随着代码老化和重构,它也很容易产生错误,因为现在第二个参数必须与第一个参数定义保持同步。例如,添加f4
需要将此值更新为 4,否则函数会返回错误的计算(并且没有警告通知此问题)。
所以最好保持两者同步。
如果它是通过变量声明的数组,那将很容易。我们可以有一个宏,它可以像这样简化表达式:float total = sumf( ARRAY(array_f) );
只需#define ARRAY(a) (a) , sizeof(a) / sizeof(*(a))
. 但是,array_f
必须在调用函数之前定义,因此它不再是复合文字。
由于是复合字面量,所以没有名字,所以不能被引用。因此,我找不到比在两个参数中重复复合文字更好的方法了。
#define LIST_F(...) (const float*)( __VA_ARGS__) , sizeof((const float*)( __VA_ARGS__)) / sizeof(float)
float total = sumf ( LIST_F( f1, f2, f3 ) );
这会奏效。将一个添加f4
到列表中会自动将size
参数更新为正确的大小。
但是,只要所有成员都是变量,这一切都可以正常工作。但是如果它是一个函数呢?该函数会被调用两次吗?比如说:float total = sumf ( LIST_F( v1, f2() ) );
,会f2()
被调用两次吗?f2()
正如在 中提到的那样,这对我来说并不清楚sizeof()
,因此理论上它可以在不实际调用的情况下知道返回类型的大小f2()
。但我不确定标准对此有何规定。有保证吗 ?它依赖于实现吗?