开发者

Can I convert a structure pointer to point to an initial anonymous member in C1x? Is this even the right question?

开发者 https://www.devze.com 2023-03-24 16:42 出处:网络
I\'m a bit confused about anonymous structures in C1x. Does the rule that a struct pointer, suitably converted, points to it\'s first member apply to an initial anonymous struct, or simply to 开发者_运

I'm a bit confused about anonymous structures in C1x. Does the rule that a struct pointer, suitably converted, points to it's first member apply to an initial anonymous struct, or simply to 开发者_运维百科the initial member of an initial anonymous struct? In particular, does this program make sense in C1x?

#include<stdio.h>

struct node {
    struct node *next;
};

/* Does C1x even allow this? Do I have to define struct node inside of inode?
 * Are anonymous struct members even allowed to have tags?
 */
struct inode {
    struct node;
    int data;
};

int main(void) {
    inode node1 = {NULL, 12};
    inode *ihead = &inode;
    node *head = (struct node *)ihead;

    /* These should work since struct inode's first member is a struct node. */
    printf("Are these equal? %c", head == &node1.next ? 'Y' : 'N');
    printf("Is next NULL? %c", head->next == NULL ? 'Y' : 'N');

    return 0;
}

This answer suggests that I may be asking about unnamed structs instead of anonymous structs. Am I completely misunderstanding the nature of anonymous structs?


/* Does C1x even allow this? Do I have to define struct node inside of inode?
 * Are anonymous struct members even allowed to have tags?
 */
struct inode {
    struct node;
    int data;
};

First, the struct node member is not anonymous. It is unnamed, but because it has a tag (node), it does not satisfy the C1x definition of "anonymous".

That aside, this is clearly allowed by the C1x grammar. Since SO doesn't really support subscripts, I've marked optional elements with square brackets; I've also elided grammar rules that are not necessary to see that this is valid:

type-specifier:
    struct-or-union-specifier
struct-or-union-specifier:
    struct-or-union [identifier] { struct-declaration-list }
struct-or-union:
    struct
    union
struct-declaration-list:
    struct-declaration
    struct-declaration-list struct-declaration
struct-declaration:
    specifier-qualifier-list [struct-declarator-list];
specifier-qualifier-list:
    type-specifier [specifier-qualifier-list]

There are also 4 constraints that need to be satisfied, but none of them apply to unnamed members, so this is syntactically valid C.

Now, on to your real question. C1x says:

A pointer to a structure object, suitably converted, points to its initial member (...), and vice versa.

Full-stop. No "unless that member is unnamed". So a pointer to node1 is also a pointer to the unnamed initial member, is also a pointer to node1.next. However, here it starts to get a little wooly. It could be that I've simply overlooked a clause, but it seems that C1x only says that:

The members of an anonymous structure or union are considered to be members of the containing structure or union.

I cannot find language saying that members of an unnamed structure are considered to be members of the containing structure. It could actually be that there is no guaranteed way to access next other than pointer-punning. I will write to some people on the committee to ask for clarification on this point.

You may also run into trouble with initialization:

Unnamed members of structure objects have indeterminate value even after initialization.


Try using node as a type name. Avoid declaring again "struct node".

struct inode {
    node n;//node is a already a defined type name, n is the var name
    int data;
};
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号