Что именно означает предварительная обработка в компиляторе

Я пытаюсь понять разницу между typedef и определить. Есть много хороших постов, особенно наэтот предыдущий вопрос о SOОднако я не могу понять пост, в котором говорится

#define это токен препроцессора: сам компилятор никогда его не увидит.
typedef это токен компилятора: препроцессор не заботится об этом.

Может ли кто-нибудь объяснить это немного подробнее. Меня смущает термин препроцессор здесь.

Ответы на вопрос(6)

выполняемый до компиляции кода компилятором.#define #include являются директивами или макросами препроцессора, поэтому механизм препроцессора выполняет код, связанный с директивами. Когда препроцессор завершен, компилятор не видит ничего из директив / макросов. Однако такие конструкции, какtypedef, if, while и т.д. понимаются компилятором.

 Lews Therin19 окт. 2012 г., 22:49
Это имеет смысл, если это так. В противном случае смысл будет бесполезным.
 Murphy31619 окт. 2012 г., 22:47
В Visual Studio, когда мы пишем код, запускается ли препроцессор во время набора текста (т.е. после того, как мы объявили препроцессор и могли бы попытаться его использовать)?
Решение Вопроса

Препроцессор - это программа, которая запускаетсядо компилятор и по существу выполняет подстановку текста. Когда вы пишете:

#define X 10

int main() 
{
    int x = X;
}

Препроцессор принимает этот файл в качестве входных данных, делает свое дело и выводит:

int main() 
{
    int x = 10;
}

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

typedef с другой стороны, это конструкция, которую понимает компилятор. Когда вы пишете:

typedef unsigned int uint_32;

Компилятор знает, чтоuint32 на самом деле псевдоним дляunsigned int, Этот псевдоним обрабатывается самим компилятором и включает в себя немного больше логики, чем простая подстановка текста. Это становится очевидным на простом примере:

typedef int my_int;

int main()
{
    unsigned my_int x;  // oops, error
}

Еслиtypedef если бы это был простой механизм подстановки текста (как, например, препроцессор), он бы работал, но он не разрешен и не сможет скомпилироваться.

что препроцессор запускается перед компилятором и изменяет исходный код перед передачей его компилятору. Таким образом, компилятор никогда не видит часть кода. Пример:

#define ONE 1
int x = ONE;

Когда вы компилируете это, препроцессор меняет это на следующее:

int x = 1;

и передает этот новый текст компилятору. Таким образом, компилятор не видит текстONE.

которая происходит очень рано. Препроцессор преобразует исходный файл в единицу перевода, включая текст заголовочных файлов, указанных#includeусловно исключая части файлов (#if, #elif, #else, #endifи варианты#ifdef а также#ifndef), и делать макро-замены. Макросы определяются через#define; макросы могут быть обнаружены препроцессором, сканирующим источник.

Препроцессор устраняет большинство строк, начинающихся с# (это только оставляет#line директивы позади и его собственные сокращенные варианты#line чтобы сообщить компилятору, откуда взялся источник). Собственно компилятор затем видит результат предварительной обработки и компилирует определенный исходный код.

Препроцессор обычно не изменяет словоtypedef, Безумный программист может определить макрос дляtypedef и препроцессор может не заботиться; программист не мог законно включить какой-либо системный заголовок, в то время как есть макрос, определенный с тем же именем, что и любое ключевое слово в языке. Иначе, тем не менее,typedef это проблема для компилятора, а не препроцессора. Так тоже естьsizeof(); это не то, что препроцессор понимает.

Обычно есть опции компилятора, чтобы вы могли видеть предварительно обработанный вывод. Заgccварианты-E а также-P.

 heretoinfinity19 янв. 2019 г., 18:35
+1: @Jonathn Leffler, я пришел сюда, пытаясь понять, что подразумевается под самим компилятором на страницах руководства, и вы ответили на него.

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

Препроцессор - это программа, которая запускается перед компилятором и выполняет все# начал инструкции, вроде#include, #define, и т.д..

В вашем конкретном случае,#define WORD newword это директива, которая говорит: «Заменить все вхождения WORD новым словом», прежде чем даже пытаться скомпилировать программу.

Если вы хотите увидеть это в действии, попробуйте запуститьcpp file.c и изучите вывод, чтобы понять, что он делает.

file.c

 #define WORD "newword"

 int main()
 {
     printf("this is word: %s\n", WORD);
     return 0;                           
 }

станет после запуска cpp

int main()
{
    printf("this is word: %s\n", "newword");
    return 0;
}

typedef, с другой стороны, используются, чтобы сказать «если я говорю оType, понимаю что я имел ввидуstruct more_complex_type«Он используется во время компиляции и останется неизменным до и послеcpp проходят.

которая происходит ДО начала компиляции. Он читает конкретные макросы и символы для замены. Обычно проходит один-два прохода. Он сканирует весь исходный файл и генерирует таблицу символов для замены или расширения макросов.

После того, как все замены сделаны, синтаксический анализатор берет на себя лексический анализ исходного файла, генерирует абстрактные синтаксические деревья, генерирует код, связывает библиотеки и генерирует исполняемые файлы / двоичные файлы.

В C / C ++ / ObjC DIRECTIVES препроцессора начинаются с '#', за которым следует имя директивы, такое как "define", "ifdef", "ifndef", "elif", "if", "endif" и т. Д.

ПЕРЕД ПОДГОТОВКОЙ:

#define TEXT_MACRO(x) L##x
#define RETURN return(0)   
int main(int argc, char *argv[])
{
    static wchar_t buffer[] = TEXT_MACRO("HELLO WORLD");
    RETURN ;
}

ПОСЛЕ ПОДГОТОВКИ:

int main(int argc, char *argv[])
{
    static wchar_t buffer[] = L"HELLO WORLD";
    return (0);
}

Если я правильно помню, у книги Kernighan и Ritchie "The C Programming Language" 2nd Edition есть пример, где они показывают, как создать свой собственный PREPROCESSOR и КАК ЭТО РАБОТАЕТ. Также компилятор Plan9 C разделил два процесса (компиляция и предварительная обработка). Позволяет вам использовать свой собственный препроцессор в нем.

Проверять, выписыватьсяИнтересный препроцессор для нескольких языков а такжеНапишите свой собственный препроцессор, Просмотр входных и выходных данных этих программ дает более глубокое понимание того, что на самом деле представляет собой препроцессор.

Еще один маленький секрет: вы можете кодировать C на латинском / немецком / испанском, если у вас есть препроцессор :)

 Murphy31619 окт. 2012 г., 22:45
Спасибо что помогает
 Aniket Inge19 окт. 2012 г., 23:04
@ Крис не заметил. Спасибо :)
 Alex19 окт. 2012 г., 22:45
+1 Правильный ответ и ты дал его первым. Хотя пример был бы хорош.
 Murphy31619 окт. 2012 г., 22:49
Пример был бы хорош
 Aniket Inge19 окт. 2012 г., 22:59
@AdamZedan и Алекс по многочисленным просьбам :-P Смотрите редактирование.

Ваш ответ на вопрос