宏内的双重评估:sizeof() 确定作为复合文字传递的数组大小的情况

问题描述

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,f3 ) );

这会起作用。将 f4 添加到列表中会自动size 参数更新为正确的大小。

但是,只要所有成员都是变量,这一切都可以正常工作。但是如果它是一个函数呢?该函数会被调用两次吗? 比如说:float total = sumf ( LIST_F( v1,f2() ) );f2() 会被调用两次吗?我不清楚这一点,因为 f2() 中提到了 sizeof(),因此理论上它可以知道返回类型的大小,而无需实际调用 f2()。但我不确定标准对此是怎么说的。有保证吗 ?它是否依赖于实现?

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...