Authors: Joseph Myers
Date: 2026-02-27
Submitted against: C23
Status: Open
Cross-references: 1013
The rules for redeclaration of structure, union and enumerated types, and for compatibility and composite type, do not address how attributes on members (not on their types) are handled. This is different from the questions in issue 1013 around "same type" when the attributes are part of the type of a member.
What are the effects of variations in attributes for redeclarations of the same type?
struct s {
[[deprecated]] int a;
int b;
} x;
struct s {
int a;
[[deprecated]] int b;
} y;
The types of the members are clearly the same (the attribute
appertains to the member, not its type), so it appears this is valid
(and both definitions of struct s, being in the same scope and using
the same tag, also thus declare the same type). Does the rule about
[[maybe_unused]] and [[deprecated]] that "An entity is considered
marked with the attribute after the first declaration that marks it."
apply to member declarations as it does to other cases of multiple
declarations of the same entity? Would subsequent references to
x.a, x.b, y.a and y.b thus all be considered references to a
deprecated entity, since x and y have the same type, where both
members are deprecated? (An example of this was raised in GCC bug
119526.)
How do such variations affect composite types?
struct s {
[[deprecated]] int a;
int b;
} x;
void
f(int i)
{
struct s {
int a;
[[deprecated]] int b;
} y = { i, i };
(i ? &x : &y)->b = 1;
}
In the composite of two compatible types in (i ? &x : &y), which
members are considered deprecated? The rule for composites of
structure and union types does not consider any information about the
members (such as attributes) that might be different, but not
affecting compatibility and not part of the types of those members.
Comment from Aaron Ballman on 2026-08-19:
Issue 1027 starts asking the right questions but there are other questions in the same area.
Related to question 1 is: how do attribute arguments impact things? e.g.,
struct S {
[[deprecated]] int i;
};
struct S {
[[deprecated("")]] int i;
};
Those are semantically equivalent but not syntactically equivalent. Probably something that users might expect to work, but do we want to encourage that kind of coding pattern by allowing it? Do attributes the implementation does not know about change the answer? e.g.,
struct S {
[[vendor::unknown("")]] int i;
};
struct S {
[[vendor::unknown]] int i;
};
Is the answer consistent for other kinds of equivalent attributes, like:
struct S {
[[gnu::unused]] int i;
};
struct S {
[[maybe_unused]] int i;
};
What about when mixed with keyword-based attributes?
struct S {
[[gnu::aligned(8)]] int i;
};
struct S {
alignas(8) int i;
};
Comment from Issues list maintainer on 2026-08-21:
This issue was discussed at the August 2026 (Ottawa) meeting of WG14. It was noted that similar issues also apply to declaration attributes on function parameters. Martin Uecker will consider declaration attributes when writing a paper for issue 1013, and Aaron Ballman volunteered to discuss attributes issues with him. Matters related to alignment are discussed in issue 1041 and issue 1044.