I am trying to understand the difference between a typedef and define. There are a lot of good posts specially at this previous question on SO, however I can\'t understand the p
A preprocessor is an "engine" executed before the compiler compiles code.
#define #include
are preprocessor directives or macros, so the preprocessor engine executes code related to the directives. When the preprocessor is done the compiler sees nothing of the directives/macros.
However constructs such as typedef
, if
, while
etc.. are understood by the compiler.
The pre-processor is a program that runs before the compiler and essentially performs text substitution. When you write:
#define X 10
int main()
{
int x = X;
}
The pre-processor take that file as input, does it's thing, and outputs:
int main()
{
int x = 10;
}
And then the compiler does its thing with the pre-processed output.
typedef
on the other hand is a construct that the compiler understands. When you write:
typedef unsigned int uint_32;
The compiler knows that uint32
is actually an alias for unsigned int
. This alias is handled by the compiler itself and involves a bit more logic than simple text substitution. This becomes obvious with a simple example:
typedef int my_int;
int main()
{
unsigned my_int x; // oops, error
}
If a typedef
were a simple text substitution mechanism (like the pre-processor is) then that would work, but it is not allowed and will fail to compile.
A preprocessor is a phase that occurs BEFORE any compilation starts. It reads specific macros and symbols to substitute. Its usually one to two pass. It scans the whole source file, and generates a symbol table to substitute or expand macros.
After all the substitutions are done, the syntax analyzer takes over lexing-parsing the source file, generating abstract syntax trees, generating code, linking libraries and generating executables/binaries.
In C/C++/ObjC Preprocessor DIRECTIVES start with '#' followed by the directive name such as "define", "ifdef", "ifndef", "elif", "if", "endif" etc.
BEFORE PREPROCESSING:
#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 ;
}
AFTER PREPROCESSING:
int main(int argc, char *argv[])
{
static wchar_t buffer[] = L"HELLO WORLD";
return (0);
}
If I remember correctly, the book "The C Programming Language" 2nd Edition, by Kernighan and Ritchie has an example, where they show how to create your own PREPROCESSOR and HOW IT WORKS. Also the Plan9 C Compiler separated the two processes(compilation and preprocessing). Allowing you to use your own PREPROCESSOR in it.
Check out An interesting preprocessor for multiple languages and Write your own pre-processor. Seeing the input and output of these programs gives you a deeper understanding of what a preprocessor actually is.
Another little secret: You can code C in latin/german/spanish if you have a preprocessor :)
The C and C++ preprocessors are a logical phase in the compilation that occurs very early on. The preprocessor converts a source file into a translation unit by including the text of header files that are specified by #include
, by conditionally eliminating parts of the files (#if
, #elif
, #else
, #endif
, and variants #ifdef
and #ifndef
), and by doing macro substitutions. The macros are defined via #define
; the macros can be detected by the preprocessor scanning the source.
The preprocessor eliminates most lines that start with #
(it only leaves #line
directives behind and its own abbreviated variants on #line
behind to tell the compiler where the source came from). The compiler proper then sees the result of the pre-processing and compiles the source code that is defined.
The preprocessor would not normally modify the word typedef
. An insane programmer could define a macro for typedef
and the preprocessor might not care; the programmer could not legitimately include any system header while there is a macro defined with the same name as any keyword in the language. Otherwise, though, typedef
is a problem for the compiler, not the preprocessor. So, too, is sizeof()
; that is not something the preprocessor understands.
There are usually compiler options to allow you to see the pre-processed output. For gcc
, the options are -E
and -P
.
It means that the preprocessor runs before the compiler and it modifies the source code before passing it on to the compiler. Thus, the compiler never sees some of the code. Example:
#define ONE 1
int x = ONE;
When you compile this, the preprocessor changes it into this:
int x = 1;
and passes that new text to the compiler. Thus, the compiler does not see the text ONE
.
When it comes to compilation, your source code pass through a lot of step. In those step, there is pre-proccessing.
The preprocessor is program that runs before the compiler, and execute all the #
started instructions, like #include
, #define
, etc..
In your particular case, #define WORD newword
is a directive that says : "Replace all occurrence of WORD with newword", before even trying to compile the program.
If you want to see it in action, try to run cpp file.c
and examine the output to understand what it does.
file.c
#define WORD "newword"
int main()
{
printf("this is word: %s\n", WORD);
return 0;
}
will become after cpp runs
int main()
{
printf("this is word: %s\n", "newword");
return 0;
}
typedef, on the other hand, are used to say "if I talk about Type
, understand that I meant struct more_complex_type
" It is used at compile time, and will stay the same before and after the cpp
pass.