C's #pragma exists so we can pass various nonstandard information to the C compiler. As alluded to above, it isn't necessarily well-liked by compilerers. Why not? After all, there are lots of good reasons to want to communicate some nonstandard information to your C compiler. If this information is not necessary to compile the program, but only to reduce warnings or produce better code, why not use #pragma ?

On its own, #pragma isn't standard enough to be useful

Of course. It's meant for nonstandard features. Only most "nonstandard" features will still be supported by almost all compilers. And each will do it differently.

Let's look at a typical example. Many C compilers support inlining of functions (at least within the same source file compilation unit) . Some heuristics are used to determine inlinability, but you might want to override them. Surely we can use #pragma to do it!

Well, almost.

SGI's C compiler lets you say #pragma inline global function (as well as some more complex options to fine-tune the inlining) to inline function wherever it appears. If you say just #pragma inline function then inlining occurs only within that scope.

(as well as some more complex options to fine-tune the inlining) to inline function wherever it appears. If you say just then inlining occurs only within that scope. Sun's Forte C compiler lets you say #pragma inline function . It has fewer options than SGI's #pragma inline (SGI is more of a supercomputing company than Sun). In fairness, judicious placement of #pragma inline can yield the same intended effect in both compilers, as long as you just want expansion throughout the file. The #pragma must appear after the function has already been declared.

. It has fewer options than SGI's (SGI is more of a supercomputing company than Sun). Compaq's C compiler requires brackets around the function names. Luckily, the brackets do no harm in the other 2 compilers.

#pragma inline (function)

#pragma inline

Dealing with compiler dependencies

By sheer luck, the form, placed after the function has already been declared, works on all 3 compilers. Except if it's not in the top-most scope, in which case it will have different semantics on SGI. And if our function is recursive , we'll have to predeclare it thenit to get one level of recursion inlined on all our platform s.

The way to deal with compiler dependencies like this (and they are unavoidable) is to use #ifdef to determine which compiler we're using. So we could say

/* Define function, then ... */ #ifdef __sgi #pragma inline global function #elif defined(__alpha) #pragma inline (function) #elif defined(__sun) #pragma inline function #endif

Abstracting #ifdef s away

which has a fighting chance of being understood by an experienced user of the compiler on her native platform.

The code above is a maintenance nightmare. If we want to add support for the new ariel Si Si compiler, we have to add a #elif clause on every inlining. The solution to this is abstraction: create some higher level construct INLINE(function) and use that instead. The definition of the construct will use #ifdef s, but they'll all be in one spot, and easy to maintain and modify.

Presumably, INLINE will be a macro, and we'll #define it appropriately.

Excuse me, did someone say "macro"? Because you cannot standardly use macros and preprocess constructs. And anything beginning with # belongs to the preprocessor.

So there is no maintainable way to use #pragma s in your code.

Epilogue