What's difference between #pragma and #ifndef? [duplicate] - c

This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
#pragma once vs include guards?
When should I use #pragma once?
When should I use #ifndef HEADER_H_INCLUDED?

The #ifndef/#define/#endif trick works on any C compiler, and on some of them it speeds up the compilation process. The #pragma trick is non-standards, and only works on few C compilers, and may result in different semantics in those that do not support it.

The difference is that the latter is C and the former is not. Never use #pragma once; always use #ifndef.
One other thing to note when using the #ifndef method is that any preprocessor symbol beginning with two underscores or an underscore followed by a capital letter is reserved and cannot be used. You should use things like #ifndef MYHEADER_H and not #ifndef _MYHEADER_H.

The construct
myfoo.h
#ifndef MYFOO_H
#define MYFOO_H
/* header information for myfoo.h */
#endif
belongs in every header-file. The trick is: you can include a header file (accidentally) more than once without thinking abaout double declarations. so this is for the preprocessor.
The #pragma is for the compiler, and a preprocessor should ignore pragmas it does not understand.

Use #pragma when you are addressing a specific compiler (or set of compatible compilers) to guide its code generation or if you are using a standardized #pragma like FP_CONTRACT or -CX_LIMITED_RANGE- that any standards-compliant compiler is going to support.
Use #ifndef and ilk if you are addressing the standard C (or C++) pre-processor and wish to have your code rendered portable across all standards-compliant compilers.
Use of any #pragma that is not defined in the C (or C++) standard renders your code non-portable. #pragma once is a bit of an exception in that it is one of the most commonly-implemented of the non-standard #pragma constructs. Its implementation, however, is not universal across standards-compliant compilers. #ifndef is.

Related

How to check the state of #pragma STDC?

Consider this code:
/* t0.c */
#pragma STDC FENV_ACCESS ON
#include "t0.h"
Then in t0.h how to check the state of STDC FENV_ACCESS?
/* t0.h */
/* how to check the state of STDC FENV_ACCESS? */
/* something like: #if STDC FENV_ACCESS == ON */
If not possible, then:
Why not possible?
Will it be useful to add this feature to the C standard?
(1) Why not possible?
It is possible with a custom cpp as rryker's answer mentioned. Otherwise, I would have said "no" because the compiler uses the pragmas and that comes after the cpp pass/stage.
(2) Will it be useful to add this feature to the C standard?
No, probably not. For the above mentioned reason.
And, because, drawing a leaf from what is already common (e.g. autoconf), we can reverse the problem to get the desired results without changing existing compilers.
Define (e.g.) a features.h:
#ifdef STDC_FENV_ACCESS_ON
#if STDC_FENV_ACCESS_ON
#pragma STDC FENV_ACCESS ON
#else
#pragma STDC FENV_ACCESS OFF
#endif
#endif
UPDATE:
Re: "custom cpp as rryker's answer mentioned": hm, where is the rryker's answer? I don't see it. –
pmor
I wrote that before rryker deleted his answer [partly] because of critique/comments from HolyBlackCat that couldn't be addressed immediately. My inference was rryker would be able to improve his answer and undelete it, so I left up the reference.
The link rryker based his answer on was specific extensions provided by clang: https://clang.llvm.org/docs/LanguageExtensions.html The features that rryker's answer referred to were: the __has_feature and __has_extension macros [since version 10].
That's the reference. However, with a bit of conjecture on my part, I'll try to summarize.
IIRC, clang's cpp is not a separate program that is only loosely connected to the compiler [e.g. like it is with gcc].
With clang, the preprocessor is a [more] tightly integrated stage within the compiler itself. My presumption is that this was [initially] done for speed and code reuse.
But, as a "side effect" of that:
clang's cpp can have much more intimate knowledge of the compiler's inner workings.
And, if it's more efficient/desirable, clang's cpp stage could also do more of the early (e.g.) pragma processing.
And, cpp could have access to (e.g.) all the -f* arguments/options the compiler sees.
So, it has all of the tools that make #if/#ifdef on the above __has_* macros feasible.
In addition to the other answers, and if t0.c is actually under your control, you may define appropriate macros whenever a #pragma is used.
/* t0.c */
#pragma STDC FENV_ACCESS ON
#define PRAG_FENV_ACCESS_ON
#include "t0.h"
This works independently of toolchain vendor. It's a variation of the same theme used to check the presence of typedefs in the preprocessor.

How to #ifdef the __builtin_prefetch function

How do I keep __builtin_prefetch() in my code, but make compilers that do not have it compile successfully? (Just doing nothing where it is found).
__builtin_prefetch() is recognised by the compiler (gcc) not the preprocessor, so you won't be able to detect it using the C preprocessor.
Since an identifier with two leading underscores is reserved for use by the implementation (so any code you use which defines such an identifier has undefined behaviour) I'd do it the other way around.
#ifdef __GNUC__
#define do_prefetch(x) __builtin_prefetch(x)
#else
#define do_prefetch(x)
#endif
and then use
do_prefetch(whatever);
where needed.
That way there is no code emitted unless it is actually needed.
Since __builtin_prefetch() accepts a variable number of arguments, you might want to adapt the above to use variadic macros (C99 and later) - if you use it with different numbers of arguments in different places in your code.
It is not exactly the best solution, but it will disable __builtin_prefetch() on all other compilers other than GCC.
#ifndef __GNUC__
# define __builtin_prefetch(x)
#endif

How to #ifdef by CompilerType ? GCC or VC++

I used #ifdef Win32 for safe calls alike sprintf_s but now I want to build project with MinGW and it's just wrong now. I need to use #ifdef VC++ or somehow like that. Is it possible?
#ifdef __clang__
/*code specific to clang compiler*/
#elif __GNUC__
/*code for GNU C compiler */
#elif _MSC_VER
/*usually has the version number in _MSC_VER*/
/*code specific to MSVC compiler*/
#elif __BORLANDC__
/*code specific to borland compilers*/
#elif __MINGW32__
/*code specific to mingw compilers*/
#endif
See the "Microsoft-Specific Predefined Macros" table of Visual C predefined macros
You could check for _MSC_VER.
Preferably, you should resort to using portable symbols. I understand sometimes those symbols may not be defined, so you can see the Predef project for an extensive list of preprocessor macros regarding standards, compilers, libraries, operating systems and architectures that aren't portable.
However, the function you specifically mention in this question has been included within the C11 standard as a part of Annex K.3, the bounds-checking interfaces (library).
K.3.1.1p2 states:
The functions, macros, and types declared or defined in K.3 and its subclauses are declared and defined by their respective headers if __STDC_WANT_LIB_EXT1__ is defined as a macro which expands to the integer constant 1 at the point in the source file where the appropriate header is first included
Thus, you should place preference upon checking __STDC_WANT_LIB_EXT1__, and only use compiler-specific symbols when that doesn't exist.

What's a better workaround compiling both OpenMP and single-threaded versions of an algorithm?

I use an ugly workaround to compile the same source code once for OpenMP and once for single-threaded code. It includes compiler macros and a double #include of a C file. I'm looking for a better solution.
OpenMP and Mac threads don't mix. This is apparently well-known. Quoting from http://www.imagemagick.org/script/architecture.php#threads .
The OpenMP committee has not defined the behavior of mixing OpenMP
with other threading models such as Posix threads. However, using
modern releases of Linux, OpenMP and Posix threads appear to
interoperate without complaint. If you want to use Posix threads ...
from Mac OS X or an older Linux release, you may need to disable
OpenMP support within ImageMagick.
I have a Python library with a C extension which scales very nicely with OpenMP, and it really involved only a scattering of #pragma statements and the right compiler flags.
I also develop on Macs. When I use my library in something other than the main thread, I get a segfault. For example, if I use OpenMP support then I can't use my library in Django.
I could of course compile without OpenMP support, but then the single-threaded batch code, which does well with OpenMP, wouldn't work.
I instead want a user-defined function to select at run-time between the OpenMP implementation and the single-threaded implementation.
The only solution I've come up with is a horrible hack where I #include the same C code twice:
#ifdef _OPENMP
#define MYFUNC static int _myfunc_openmp
#include "algorithm.c"
#undef MYFUNC
#define MYFUNC static int _myfunc_single
#include "algorithm.c"
int myfunc(int arg) {
if (omp_get_num_threads() <= 1) {
return _myfunc_single(arg);
} else {
return _myfunc_openmp(arg);
}
}
#else
#define MYFUNC int myfunc
#include "algorithm.c"
#endif
and where "algorithm.c" looks like
MYFUNC(int arg) {
#ifdef _OPENMP
#pragma omp for ...
#endif
... algorithm here ...
}
This does work, but it feels like I'm taking the wrong approach.
I tried using OpenMP's "if()" clause, as in
int in_parallel = (omp_get_num_threads() > 1);
#pragma omp for ... if(in_parallel)
but that still causes OpenMP on a thread to segfault my program. I presume that it's allocating space for the lock in the critical section of my code, even though it's not needed.
Do you know a better way to have the same algorithm used for both the OpenMP and non-OpenMP code paths?
If you have C99 (gcc and clang do for that case) you can use the _Pragma operator. It is useful especially inside macros:
#ifdef WITH_OPENMP
# define PARALLEL_FOR _Pragma("omp for")
#else
# define PARALLEL_FOR
#endif
Now you can just prefix the appropriate for loops with that macro, and thus avoid all other the ugly #if/#else in the rest of the code, which make it difficult to maintain.
The double inclusion per se of the file doesn't look wrong to me. Having a special case that is compiled statically without OpenMp avoids any run time decision that OpenMp could try to take.
What I wouldn't do, is passing storage specification, return type and name in one macro. In any case having the two functions visible by the linker costs you nothing, so the static is superfluous. The only thing that you should watch is that linker symbols starting with an underscore are reserved, better rename them to something decent.

What is replacement of __attribute__ in ISO C standard?

What is the replacement of __attribute__ in ISO C standard?
I want to port my software which is compiler independent.
There isn't one.
One solution is to abstract the attributes behind macros. e.g.:
#ifdef __GNUC__
#define UNUSED __attribute((unused))__
#else
#define UNUSED
#endif
...
void function(void) UNUSED;
There is no general replacement for the wide range of facilities that this gcc extension offers. Most other compilers that are not gcc compatible use #pragma to achieve similar goals. Since C99, C has the _Pragma operator that allows you to spew pragmas in the middle of your code (not only on proper lines) and to compose the contents of a pragma with macros. But then you still have to do specific "translations" of individual features to the corresponding pragma syntax of your target compiler.

Resources