如果我有这些结构:
typedef struct { int x; } foo;
typedef struct { foo f; } bar;
通常你会通过 b.f.x
访问 x
,但是有没有办法设置它,这样你就可以访问元素 x
而无需引用f
?
bar b;
b.x = ...
我的第一个直觉是你不能,因为如果两个子结构都有一个成员 x 并且我无法弄清楚编译错误会是什么,那么可能会发生名称冲突。不过,我记得我曾在一些可行的框架中工作过。
在 C++ 中,我曾经在一个存在 bar
的框架中工作过,您可以从不同的类作为成员变量 this->x
访问它的成员。我正在尝试弄清楚如何做到这一点。
最佳答案
你可以用 C11:
§ 6.7.2.1 -- 11
An unnamed member whose type specifier is a structure specifier with no tag is called an anonymous structure; an unnamed member whose type specifier is a union specifier with no tag is called an anonymous union. The members of an anonymous structure or union are considered to be members of the containing structure or union. This applies recursively if the containing structure or union is also anonymous.
所以这段代码可能工作:
#include <stdio.h>
typedef struct { int x; } foo;
typedef struct { foo; } bar;
int main(void)
{
bar b;
b.x = 1;
printf("%d\n", b.x);
}
这里的问题是,不同的编译器在我的测试中对于 typedef 是否可以作为没有标签的 struct 说明符是可以接受的 标准规定:
§ 6.7.8 -- 3
In a declaration whose storage-class specifier is
typedef
, each declarator defines an identifier to be a typedef name that denotes the type specified for the identifier in the way described in 6.7.6. [...] Atypedef
declaration does not introduce a new type, only a synonym for the type so specified.
(强调我的)——但是 synonym 是否也意味着 typdef-name 说明符可以替换为 struct 说明符? gcc
接受这个,clang
不接受。
当然,没有办法用这些声明来表达foo
类型的整个成员,你牺牲了你的命名成员f
。
关于您对名称冲突的疑问,当您在 bar
中放置另一个 int x
时,gcc
必须这样说:
structinherit.c:4:27: error: duplicate member 'x'
typedef struct { foo; int x; } bar;
^
为避免歧义,您可以重复结构,可能#define
d 作为宏,但当然,这看起来有点难看:
#include <stdio.h>
typedef struct { int x; } foo;
typedef struct { struct { int x; }; } bar;
int main(void)
{
bar b;
b.x = 1;
printf("%d\n", b.x);
}
但是任何符合标准的编译器都应该接受这个代码,所以坚持这个版本。
gcc
接受的语法,但由于标准的措辞并没有使其 明确 允许这个,唯一安全的赌注是假设它是被禁止的,所以 clang
不应该归咎于此......
如果你想通过 either b.x
or b.f.x
引用 x
,您可以像这样使用额外的匿名 union :
#include <stdio.h>
typedef struct { int x; } foo;
typedef struct {
union { struct { int x; }; foo f; };
} bar;
int main(void)
{
bar b;
b.f.x = 2;
b.x = 1;
printf("%d\n", b.f.x); // <-- guaranteed to print 1
}
这不会因为
而导致别名问题§ 6.5.2.3 -- 6
One special guarantee is made in order to simplify the use of unions: if a union contains several structures that share a common initial sequence (see below), and if the union object currently contains one of these structures, it is permitted to inspect the common initial part of any of them anywhere that a declaration of the completed type of the union is visible. Two structures share a common initial sequence if corresponding members have compatible types (and, for bit-fields, the same widths) for a sequence of one or more initial members
关于c++ - 通过更高级别的结构访问子变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44523717/