聚合初始化,将成员指针设置为相同的struct成员 [英] Aggregate initialization, set member pointer to same struct member

查看:140
本文介绍了聚合初始化,将成员指针设置为相同的struct成员的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

是否可以使用聚合初始化将指针 aptr 指向 a 的指针,相同的 struct 吗?

Is it possible to use aggregate initialization to make a pointer aptr point to a which is a member of the same struct ?

struct S {
  int a;
  int* aptr;
};

int main() {
  S s = {
    .a = 3,
    .aptr = &a //point aptr to a
  };
  return 0;
}

问题是同时针对 C C ++

The question is for both C and C++.

推荐答案

有效的初始化应为:

struct S {
  int a;
  int* aptr;
};

int main() {
    struct S s = {.a = 3, .aptr = &s.a};
    printf("%d", *s.aptr);
}

工作样本:

C11 GNU

< a href = https://wandbox.org/permlink/b8iiW5FhAdtH5Ryr rel = nofollow noreferrer> C ++ 2a GNU

关于初始化的正确性:

对于C:


初始化列表表达式彼此之间不确定地排序,因此未指定发生任何副作用的顺序。

The evaluations of the initialization list expressions are indeterminately sequenced with respect to one another and thus the order in which any side effects occur is unspecified.

对于C ++:


在括号初始列表的初始值列表中,初始值子句包括包扩展产生的所有子句( [temp.variadic] ),按照它们出现的顺序进行评估
也就是说,与给定的初始化程序子句相关的每个值计算和副作用都在与初始化程序的逗号分隔列表中跟在其后的任何初始化程序子句相关的每个值计算和副作用之前进行排序。 -list

但是,尽管可以观察到差异,但是在这种情况下,表达式的计算顺序似乎无关紧要,因为您实际上并没有访问 sa 的值,所以只能访问此时可访问的地址。

However, despite the differences we can observe, the order in which the expressions are evaluated does not seem matter in this case, since you're not actually accessing the value of s.a, just its address which is accessible at this point.

所以这是 C C ++ 的正确初始化。

So this is a correct initialization both for C and C++.

此代码要注意的地方,在 MSVC 中, C ++ 中的编译错误:

Something to note with this code, in MSVC, there is a compilation error in C++:


use of designated initializers requires at least '/std:c++latest'


使用 std:c ++ latest 错误更改为:

Using std:c++latest the error changes to:


designated and non-designated initializers is nonstandard in C++


但是,编译器的范围从 clang 3.1 clang 10.0 gcc 4.9.0 gcc 10.0 C ++ 03 C ++ 2a 即可编译,没有警告。

However, compilers that range from clang 3.1 to clang 10.0 and gcc 4.9.0 to gcc 10.0 with C++03 to C++2a compile fine with no warnings.

C ++ 20 中引入的指定初始值设定项,因此实际上不接受它们是正确的,例如MSVC仍然不接受 / std:c ++ 20 ,尚无法使用它们,看起来像 gcc clang 始终为这些初始化程序提供支持。

Designated initializers where introduced in C++20, so it is actually correct not to accept them, as MSVC still does not accept /std:c++20, it is not possible to use them yet, it also looks like gcc and clang always provided support for these initializers.

话虽如此,解决方案是:

That being said, a second solution would be:

struct S {
    int a;
    int* aptr;
};

int main() {
    struct S s = { 3, &s.a };
    printf("%d", *s.aptr);
}

第二个初始化版本的编译在每个测试的编译器中都没有问题,因此可以假设

This second version of initialization compiles with no issues in every compiler tested, so it's fair to assume that it is more portable.

第一个版本可能更易于阅读,并且可以更轻松地识别初始化中的错误,这是指定初始化器的优点之一。

The first version is probably more easily readable and allows for a easier identification of errors in initialization, one of the advantages of designated initializers.

这篇关于聚合初始化,将成员指针设置为相同的struct成员的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆