Some Name
Some Name

Reputation: 9521

Understanding declarations in the same scope

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

Answers (2)

Gunther Schulz
Gunther Schulz

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

0___________
0___________

Reputation: 67546

case 8

 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? 

case 7

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

Related Questions