Область действия #define в одном главном файле - PullRequest
0 голосов
/ 31 марта 2012

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

#include<stdio.h>
#include<stdlib.h>
#define A 100
void fun();
int main()
{

    fun();
    printf("%d\n",A);
    system("pause");
    return 0;
}
void fun()
{
    #undef A

}

Вывод программыравен 100, хотя, по моему мнению, это должна была быть ошибка компилятора.Пожалуйста, объясните, почему?

Ответы [ 5 ]

2 голосов
/ 31 марта 2012

Препроцессор работает с текстом вашего исходного кода и делает это до того, как собственно компилятор начнет работать .

По сути, ваш компиляторработает с файлом, который выглядит как

/* Lots of code from the included files omitted */
void fun();
int main()
{

    fun();
    printf("%d\n",100);
    system("pause");
    return 0;
}
void fun()
{

}

Так что запуск и печать 100 - это именно то, что вы ожидаете.

Обратите внимание, что все директивы препроцессора пропали, и что все экземплярыA между define и undef были заменены на 100.

Следует помнить следующее:

  • Запускается препроцессор, изменяя text
  • Затем компилятор запускает результат
1 голос
/ 31 марта 2012

Вы не можете запускать команды препроцессора в функциях. Они удалены из скомпилированного кода. Вот почему они называются препроцессором: они выполняются и удаляются до компиляции программы. В fun () вы не определяете число 100.

1 голос
/ 31 марта 2012

Препроцессор делает один проход через текст программы во время компиляции.К тому времени, когда программа запускается, все директивы уже давно ушли.

Первоначально препроцессор фактически представлял собой отдельную программу, которая понимала C только в той степени, в которой он анализировал токены таким же образом.После создания макро-расширенной версии программы во временном файле был запущен настоящий компилятор.Сегодня он интегрирован в компилятор, но таким образом, что эффект тот же.

Так началось соглашение об использовании макрокоманд в верхнем регистре, т. Е. Чтобы подчеркнуть их существеннодругой характер.Вы все еще можете заставить компилятор выводить расширенный, но некомпилированный промежуточный текст.Это иногда полезно при отслеживании ошибок и понимании сложной условной компиляции.

0 голосов
/ 01 апреля 2012
Расширение макроса

выполняется на этапе предварительной обработки, который является этапом перед компиляцией. Если вы хотите посмотреть, как код выглядит после этого шага, попробуйте скомпилировать с опцией только предварительной обработки.

, например

gcc -E myfile.c > myfile.ppout

и прочитайте вывод.

0 голосов
/ 31 марта 2012

Макросы выполняются во время компиляции (фактически перед компилятором).

...