请考虑以下代码段:
struct my_struct {
int a;
int b;
int c;
};
void my_func(unsigned long x)
{
struct my_struct m[] = {
{ 0, 1, 2 },
{ 11, 22, htonl(x) },
{ 0x1, 0xa, 0xbb }
};
...
}
在结构初始化块内调用函数是否合法/可移植?
答案 0 :(得分:4)
是的,这是合法的,只要您使用 automatic 存储持续时间初始化对象(如您的示例)。对于静态存储持续时间不合法的对象,因为此类对象在其初始值设定项中仅允许恒定表达式。
还请记住,尽管在C中,初始化器表达式的求值相对于彼此不确定地排序。这意味着,如果您在初始化器之间有多个函数调用,而这些函数的结果取决于某些共享状态,则这些初始化器的行为可能无法预测
int foo()
{
static int a;
return ++a;
}
int main()
{
struct { int x, y; } s = { foo(), foo() };
/* Can be `{ 1, 2 }` or `{ 2, 1 }`... */
}
关于可移植性,可以注意到C89 / 90不允许这样做(在C89 / 90中,所有{}
括起来的初始化器都必须是常量表达式,即使对于自动对象也是如此),但是最受欢迎的是C89无论如何,/ 90编译器都支持。
答案 1 :(得分:3)
在结构初始化块内调用函数是否合法/可移植?
[...]
| initializer-list: | designationopt initializer | initializer-list , designationopt initializer
〜> 初始化程序列表由初始化程序组成
对于具有静态存储持续时间的对象,初始化器中的所有表达式都应为常量表达式或字符串文字
〜> 初始化程序由表达式组成。 (用于具有静态存储持续时间的对象的常量表达式)
表达式是一个运算符和操作数的序列,它们指定值的计算,或者指定对象或函数,或者产生副作用,或者执行它们的组合。
〜> 函数调用是一个表达式。