[C] Identifier와 Name space

Code 1.

#include <stdio.h>

int main(void)
{
    int a = 42;
    printf("%d\\\\n", a);
    int a = -42;
    printf("%d\\\\n", a);
}

Code 2.

#include <stdio.h>
int a = 42;

int main(void)
{
    printf("%d\\\\n", a);
    int a = -42;
    printf("%d\\\\n", a);
}

Code 3.

#include <stdio.h>
int a = 0;

int main(void)
{
    int a = 42;
    printf("%d\\\\n", a);
    {
        int a = -42;
        printf("%d\\\\n", a);
    }
    printf("%d\\\\n", a);
}

Code 4.

#include <stdio.h>

int main(void)
{
    struct s {
        int s;
    };
    struct s s = {.s = 42};
    printf("%d\\\\n", s.s);
}

Code 5.

#include <stdio.h>

int main(void)
{
    typedef struct s {
        int s;
    } s;
    s s = {.s = 42};
    printf("%d\\\\n", s.s);
}

위 코드들은 정상 작동할까? 컴파일되지 않으면 그 이유는 무엇이고, 잘 작동한다면 그 이유는 무엇일까?

해답은 C언어의 Identifier(식별자), 그리고 Name Space에 있다.

Note) 이 글은 C99 표준(ISO/IEC 9899)을 바탕으로 설명합니다. 가장 최신 표준인 C23(ISO/IEC 9899:2023)도 추가되는 요소들(constexpr 등)에 대한 설명이 추가될 뿐, 기본 개념은 다르지 않습니다.

1. Identifier

C언어 표준은 Identifier를 다음과 같의 정의한다. (C99 6.2.1 Clause 1)

An identifier can denote an object; a function; a tag or a member of a structure, union, or enumeration; a typedef name; a label name; a macro name; or a macro parameter. (...)

식별자(Identifier)는 다음을 가리킨다.