tags:

views:

407

answers:

6

I want some examples of C preprocessor directives, such as:

#define pi 3.14
#define MAX 100

I know only this. I want to know more than this, more about preprocessor directives.

+9  A: 

The biggest example would be

 #include<stdio.h>

But there are a fair amount. You can also define macros:

 #define MAX(X,Y) (((X) > (Y)) ? (X) : (Y))

And use header guards

#ifndef A_H
#define A_H

// code

#endif

There are proprietary extensions that compilers define to let you give processing directives:

#ifdef WIN32 // WIN32 is defined by all Windows 32 compilers, but not by others.
#include <windows.h>
#else
#include <unistd.h>
#endif

And the if statement cause also be used for commenting:

#if 0

int notrealcode = 0;

#endif

I often use the preprocessor to make debug builds:

#ifdef EBUG
printf("Debug Info");
#endif

$ gcc -DEBUG file.c //debug build
$ gcc file.c //normal build

And as everyone else has pointed out there are a lot of places to get more information:

Tom Ritter
Always protect all arguments in macro expansions with parentheses. Consider the expansion of '`MAX(x|3, y without parenthesizing '(X > Y)' as '((X) > (Y))', it doesn't evaluate to what you would expect.
Jonathan Leffler
Your header guard names are illegal.
anon
What Neil is referring to is that in C (and C++) identifiers beginning with an underscore and capital letter are reserved for use by the OS and other elements of the language implementation.
Tyler McHenry
@Tyler Certainly not reserved for the OS - for the C++ compiler and libraries.
anon
@Neil so, all those headers in /usr/include/linux that define identifiers starting with an underscore and a capital letter are in violation of the C standard?
Tyler McHenry
I've never seen that before (nor had a problem). But I changed it for "good practices" purposes.
Tom Ritter
@Tyler: No. They are reserved for use by the implementation -- by system libraries and by the compiler. In other words, they are reserved *for* headers such as those under /usr/include/linux. That's the entire point. Those headers, being system headers, are allowed to use a special class of names, so that they can avoid naming conflicts with *your* code. So if *your* code starts using *their* names, that whole system falls apart, and you risk getting conflicts.
jalf
@jalf I understand the rationale behind reserving identifiers. I was taking issue with Neil nit-picking my comment that they're reserved for the OS in addition to the compiler, since obviously kernel headers use them and they're not part of the compiler (they're part of the kernel).
Tyler McHenry
@Tyler The standard makes no mention of the operating system when it comes to reserved names, only the language implementation. If the files you refer to are part of the specific C or C++ implementation, then they are legal. If they come from elesewhere, like a whole raft of POSIX headers do, for excample, then they are not. Nothing new there, sadly.
anon
+5  A: 

Are you entirely familiar with the fundamentals, e.g. as covered on wikipedia? Or do you need an elementary tutorial? or what?

Alex Martelli
+4  A: 

Maybe one of

can be of help.

Dirk Eddelbuettel
+2  A: 

There's a lot more to the processor than #define. Don't forget #include and conditional compilation.

http://en.wikipedia.org/wiki/C%5Fpreprocessor

Nosredna
A: 

This will stop the compile if the conditional fails.

#define WIDTH 10
#define HEIGHT 20

#if WIDTH < HEIGHT
#    error "WIDTH must be greater than or equal to HEIGHT"
#endif

C Preprocessor Man pages http://gcc.gnu.org/onlinedocs/cpp/index.html

DanM
+2  A: 

The most important one:

#ifndef THIS_HEADER_H
#define THIS_HEADER_H

// Declarations go here    

#endif //THIS_HEADER_H

This keeps a header file from being included in a single C file multiple times.

For gcc sources I like to use __LINE__, as in:

printf("%s: %d: Some debug info\n", __func__, __LINE__);

For debugging purposes.

Rob Jones
Unless you are writing the compiler, you should avoid defining symbols starting with '_'.
Jonathan Leffler
Yup. I fixed it to be more general.
Rob Jones