Являются главными и fopen действительными именами переменных?

В стандарте C указано, что имена переменных не должны совпадать со стандартными ключевыми словами C и стандартными именами функций. Тогда почему код ниже компилируется без ошибок?

#include <stdio.h>

int main()
{
    int main = 10;
    printf("Magic is %d", main);
    return 0;
}

См. также http://codepad.org/OXk4lZZE

В ответе ниже, ouah пишет

main не является зарезервированным идентификатором, и ему разрешено указывать переменные как main в C

поэтому, рассматривая программу ниже, означает ли это, что fopen также не зарезервировано?

#include <stdio.h>

int main()
{
    int fopen = 10;
    printf("Magic is %d", fopen);
    return 0;
}

Ответ 1

Программа является действительной программой C.

main не является зарезервированным идентификатором, и ему разрешено указывать переменные как main в C.

То, что вы не можете сделать, это указать переменную main в области файлов, но это то же самое, что и с другими переменными, которые конфликтуют с функцией с тем же именем:

Это неверно:

int main = 0;

int main(void)
{
}

По тем же причинам это неверно:

int foo = 0;

int foo(void)
{
    return 0;
}

EDIT:, чтобы обратиться к редактированию вопроса OP, вторая программа в вопросе OP также действительна, так как C говорит

(C11, 7.1.3p1) "Все идентификаторы с внешней связью в любом из следующих подклассов (включая будущие направления библиотек) и errno всегда зарезервированы для использования в качестве идентификаторов с внешняя связь".

но идентификатор переменной fopen имеет область действия блока и никакой связи в примере программы.

Ответ 2

По умолчанию глобальные переменные и функции extern в природе, где, как и в области блока, по умолчанию они auto.

Чтобы проверить, как компоновщик решает символы, проверьте здесь