Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Suspicious case statement syntax accepted by C compilers

I found a long-standing bug is some code (I had written the code, so my it's own fault). The thing that I cannot understand is why it was not spotted by the compiler.

The code is in C, which I have been using for many years and I always consider myself knowledgeable about, but it makes no sense to me. I have tried similar code under both Visual Studio and Gnu C compilers and both accept it.

The code is:

enum TYPE_ENUMS {
    TEST_CASE = 1,
};

int main()
{
    int caseVal = 1;
    switch (caseVal) {
    TEST_CASE:
        printf("1\n");
    default:
        printf("Unknown Case %d\n", caseVal);
        break;
    }   
}

Can anyone explain how an enum can be part of a case statement without a "case" before it. Should this be valid code? and if so, is there a use for it?

like image 872
user2881914 Avatar asked Jan 25 '23 16:01

user2881914


1 Answers

What you have is actually a label that can be the target of a goto statement, and there's no restriction that says ordinary labels can't appear inside of a switch block.

Labels are in a separate namespace from ordinary identifiers which includes enum constants, so they can coexist without ambiguity. This is spelled out in section 6.2.3p1 of the C standard:

If more than one declaration of a particular identifier is visible at any point in a translation unit, the syntactic context disambiguates uses that refer to different entities. Thus, there are separate name spaces for various categories of identifiers, as follows:

  • label names (disambiguated by the syntax of the label declaration and use);
  • the tags of structures, unions, and enumerations (disambiguated by following any of the keywords struct, union, or enum);
  • the members of structures or unions; each structure or union has a separate namespace for its members (disambiguated by the type of the expression used to access the member via the . or -> operator);
  • all other identifiers, called ordinary identifiers(declared in ordinary declarators or as enumeration constants).
like image 53
dbush Avatar answered Feb 04 '23 00:02

dbush