Reputation: 9521
This is a language-lawyer question about ISO C.
I'm trying to understand how declaration is defined in the Standard. I use N1570. Consider the following cases:
Case 1.
int a;
extern int a; //compatible types, external linkage, well-defined behavior
Case 2.
extern int a;
int a; //well-defined behavior, external linkage, well-defined behavior
Case 3.
int a;
static int a; //6.2.2/6.9.2UB, linkage-disagreement
Case 4.
static int a;
extern int a; //6̶.̶2̶.̶2̶/̶6̶.̶9̶.̶2̶ ̶U̶B̶,̶ ̶l̶i̶n̶k̶a̶g̶e̶-̶d̶i̶s̶a̶g̶r̶e̶e̶m̶e̶n̶t̶
//as @EricPostpischil mentioned in the comment
//it is well-defined in 6.2.2
Case 5.
int a;
long a; //6.7.2 UB incompatible types
Case 6.
int a;
const int a; //6.7.2/6.7.3 incompatible types, different qualifiers
Case 7.
enum{
a
};
enum{
a //UB, why?
};
Case 8.
enum {
a
};
const unsigned char a; //UB, why?
Case 1-4
The explanation is clear and well-defined in the Standard.
6.2.2(p7)
:
If, within a translation unit, the same identifier appears with both internal and external linkage, the behavior is undefined.
Case 5
It is explained in the sections 6.2.7(p1)
:
If, within a translation unit, the same identifier appears with both internal and external linkage, the behavior is undefined.
and 6.7(p4)
:
All declarations in the same scope that refer to the same object or function shall specify compatible types.
Case 6
It is explained by 6.7.3(p10)
:
For two qualified types to be compatible, both shall have the identically qualified version of a compatible type
Case 7-8.
Unclear. I did not find any formal references in the Standard related to them. 6.2.7(p1)
states:
For two enumerations, corresponding members shall have the same values.
case 7 satisfies that requirements.
so I don't see any problems.
I did not find anything related to case 8 explicitly so as if it is not defined in the Standard it should be UB.
Can you help to find an explanation in the Standard of the Case 7 and Case 8?
Upvotes: 2
Views: 156
Reputation: 625
Case 7
It is explained by 6.7.2.3 paragraph 1, 4 and 5 (page 137) (emphasis is mine)
1 A specific type shall have its content defined at most once.
4 All declarations of structure, union, or enumerated types that have the same scope and use the same tag declare the same type. Irrespective of whether there is a tag or what other declarations of the type are in the same translation unit, the type is incomplete [footnote 129)] until immediately after the closing brace of the list defining the content, and complete thereafter.
5 Two declarations of structure, union, or enumerated types which are in different scopes or use different tags declare distinct types. Each declaration of a structure, union, or enumerated type which does not include a tag declares a distinct type.
So an example of identical types of enums [if not for paragraph 1] would be like
enum TagNameA
{
a
};
enum TagNameA
{
a
};
Case 8 It is explained by 6.7.2.2 paragraph 3 (page 136) (emphasis is mine)
The identifiers in an enumerator list are declared as constants that have type int and may appear wherever such are permitted [footnote: 127)]
...
[footnote 127)] Thus, the identifiers of enumeration constants declared in the same scope shall all be distinct from each other and from other identifiers declared in ordinary declarators.
where in Case 8
const unsigned char a;
is an ordinary declarator for a
that is not distinct from the enumeration constant identifier a
.
Upvotes: 3
Reputation: 67546
enum {
a
};
const unsigned char a; //UB, why?
It is not UB. It is semantic error. UB may happen only runtime.
duplicate identifier 'a'. Consider
int b = a; //which a?
enum{
a
};
enum{
a //UB, why?
};
It is not UB. It is semantic error. UB may happen only runtime.
duplicate identifier 'a'. Consider
int b = a; //which a?
Upvotes: 0