how to use #ifdef with an OR condition? - c

Sorry for asking very basic question. I would like to set OR condition in #ifdef directive.?
How to do that ?
I tried
#ifdef LINUX | ANDROID
...
..
#endif
It did not work? What is the proper way?

Like this
#if defined(LINUX) || defined(ANDROID)

OR condition in #ifdef
#if defined LINUX || defined ANDROID
// your code here
#endif /* LINUX || ANDROID */
or-
#if defined(LINUX) || defined(ANDROID)
// your code here
#endif /* LINUX || ANDROID */
Both above are the same, which one you use simply depends on your taste.
P.S.: #ifdef is simply the short form of #if defined, however, does not support complex condition.
Further-
AND: #if defined LINUX && defined ANDROID
XOR: #if defined LINUX ^ defined ANDROID

Related

Is there a constant that clang recognizes on mac os x? [duplicate]

I am fairly new to C++. I am currently working on a group project and we want to make our classes compatible with both the lab computers (Windows) and my computer (Mac OS X).
Here is what we have been putting at the top of our files:
#ifdef TARGET_OS_X
# include <GLUT/glut.h>
# include <OpenGL/OpenGL.h>
#elif defined _WIN32 || defined _WIN64
# include <GL\glut.h>
#endif
I realize this question has been asked before but my searches have been giving me conflicting answers such as "_MAC", "TARGET_MAC_OS", "MACINTOSH", etc. What is the current and correct declaration to put in the #ifdef statement to make this compatible with Mac? Right now it is not working.
Thank you!
According to this answer:
#ifdef __APPLE__
#include "TargetConditionals.h"
#ifdef TARGET_OS_IPHONE
// iOS
#elif TARGET_IPHONE_SIMULATOR
// iOS Simulator
#elif TARGET_OS_MAC
// Other kinds of Mac OS
#else
// Unsupported platform
#endif
#endif
So in short:
#ifdef __APPLE__
#include "TargetConditionals.h"
#ifdef TARGET_OS_MAC
#include <GLUT/glut.h>
#include <OpenGL/OpenGL.h>
#endif
#elif defined _WIN32 || defined _WIN64
#include <GL\glut.h>
#endif
It depends on the compiler. #ifdef __APPLE__ works for gcc.
According to Microsoft, _WIN32 will cover both the 32-bit and 64-bit versions of Windows. And __APPLE__ works for Clang (at least in Mavericks). So one correct way to write the ifdefs above is:
#ifdef __APPLE__
DoSomething();
#elif _WIN32
DoSomethingElse();
#else
GenerateErrorOrIgnore
Small correction: #ifdef TARGET_OS_MAC will get you always true on both OS X and iOS, as it is defines either 0 or 1 depending on platform, but when APPLE is defined, TARGET_OS_MAC is defined as well, so checking it inside the #ifdef APPLE is worthless.
You might want to use #if TARGET_OS_MAC instead. Same for all TARGET_* macros.

#elif compiler directive in C using Codeblocks and MinGW in Windows

I am programming in C using CodeBlocks in Windows with the MingGW compiler that comes bundled with the most recent version. I am trying to get some compiler directives to work to demonstrate conditional compilation.
Below is my code. However, it would seem code blocks or MinGW does not like the #elif parts. If I set my defined macro value DEBUG_MODE to either 3 or 2 neither of the #elif structures appear to work.
Also, codeblocks is greying out the code that falls inside both #elif structures. Have I miscomprehended something about these compiler directives, or is it that not all versions of C support #elif? I know I can solve if just by nesting #if and #else structures, but Id like to know if #elif should work this way. Code below.
Ok so initially I made a schoolboy error and got my conditional logic around the wrong way. I have fixed it now but for the sake of completeness here it is.
Amended code below Codeblocks now behaves as I expect, mostly. The code colouring is off but functionally as I would expect.
#include <stdio.h>
#include <stdlib.h>
#define DEBUG_MODE 3
char * trace;
char * traceDesc;
int main()
{
trace = "main method normal start";
traceDesc = "Main method runs the body of the program to demonstrate compiler directives #if and #elif ";
#if DEBUG_MODE <= 3
printf("Program Begun!\n");
#elif DEBUG_MODE <= 2
printf("trace message %s :", trace);
#elif DEBUG_MODE <= 1
printf("Description message %s :", traceDescr);
#endif
return 0;
}
If I set my defined macro value DEBUG_MODE to either 3 or 2 neither of
the #elif structures appear to work.
That's because you say:
#if DEBUG_MODE >= 1
...
#elif
The condition was true and none of the subsequent blocks would be executed.
Depending upon what you're trying to achieve, you might want to say:
#if DEBUG_MODE >= 1
...
#endif
#if DEBUG_MODE >= 2
...
#endif
#if DEBUG_MODE >= 3
...
#endif

C Pre-processor directives, Is this correct syntax? #Ifdef foo || bar

I have a pre-processor directive as such,
//#define SPEC_CONTROL // Is not defined, but can be if need be
#define SPEC_A_CONTROL // Is defined
#ifdef SPEC_CONTROL || SPEC_A_CONTROL
; // do something
#else
; // do something else
#endif
Is it correct syntax to use the || in the manner I did?
I can assure yout that at least
#if defined(SPEC_CONTROL) || defined(SPEC_A_CONTROL)
works on Windows and several UNIX platforms. Im not sure about
#ifdef SPEC_CONTROL || SPEC_A_CONTROL
You can use boolean logic in a C preprocessor directive by using the if defined directive.
See this post for more information:
C Preprocessor testing definedness of multiple macros

C - How do you ignore certain code depending on the OS (so one source code to fit all)

I want to make the source of my program cross-platform, and so far so good. I have a couple of functions that only really differ in syntax, so I am checking some defines at the start to see if its windows or linux and setting a variable to 1 or 0 depending on which one it is. My thinking was that I could do an if statement check on that variable to skip the incorrect syntax usage. I have realised now that it won't compile because the compiler still 'sees' the offending code. Can you you
#ifdef
to compartmentalize certain functions and call them within the code? Any suggestions?
You have to enclose the entire non cross-platform section between #ifdefs.
For instance:
int gettimeofday(struct timeval *tp, void *tzp)
{
#ifdef WIN32
struct _timeb timebuffer;
_ftime(&timebuffer);
tp->tv_sec = timebuffer.time;
tp->tv_usec = timebuffer.millitm * 1000;
return 0;
#else
tp->tv_sec = time(NULL);
tp->tv_usec = 0;
return 0;
#endif
}
Like this the compiler won't see the offending code since it is removed at the preprocessing step.
Of course you can, that's pretty much the standard way of doing that, at least for small parts of code. For bigger chunks, you might want to use the buildsystem instead, and have platform-specific code in separated files (foo_win.c, foo_unix.c); then, depending on the OS, you compile and link in the application only the right ones.
There are a lot of preprocessor defines that will tell you OS, compiler, architecture and other things; take a look at how Qt detects the OS or the compiler.
cpp -d M < /dev/null > somefile will show the default feature test macro settings (#define values) you can expect from a compiler - for the macros (#ifdef) stuff you want to test for. You have to run this on every system, plus some compilers add macros by default e.g. gcc.
#ifdef _SUN_OS
// put all Sun OS code here
#endif
You will have to find the macros to identify all of your platforms.
Yes, in the simplest case and assuming for example a function called foo() you can do something like that...
/* Are we on a Windows platform ? */
#if defined(_WIN32) || defined(_WIN64) || defined(__WINDOWS__) || defined(__TOS_WIN__)
void foo( ... ) {
/* windows implementation */
}
/* Are we on a Linux platform ? */
#elif defined(__linux__) || defined(__linux) || defined(linux) || defined(__gnu_linux__)
void foo( ... ) {
/* linux implementation */
}
/* Are we on a Unix platform ? */
#elif defined(__unix__) || defined(__unix) || defined(unix) \
|| defined(__CYGWIN__) || ( defined(__APPLE__) && defined(__MACH) )
void foo( ... ) {
/* unix implementation */
}
/* Are we on Unsupported platform? */
#else
void foo( ... ) {
/* generic implementation */
}
#endif
Another option is to have different header files for each OS that implement the different versions of the function(s), and then conditionally #include the appropriate one.
Assuming some header files called: myproj_win32.h, myproj_linux.h, myproj_unix.h, myproj_generic.h you could do something like this...
/* Are we on a Windows platform ? */
#if defined(_WIN32) || defined(_WIN64) || defined(__WINDOWS__) || defined(__TOS_WIN__)
#include "myproj_win32.h"
/* Are we on a Linux platform ? */
#elif defined(__linux__) || defined(__linux) || defined(linux) || defined(__gnu_linux__)
#include "myproj_linux.h"
/* Are we on a Unix platform ? */
#elif defined(__unix__) || defined(__unix) || defined(unix) \
|| defined(__CYGWIN__) || ( defined(__APPLE__) && defined(__MACH) )
#include "myproj_unix.h"
}
/* Are we on Unsupported platform? */
#else
#include "myproj_generic.h"
#endif
Only the correct version of the implementation will be compiled. There are more options, but those should be fine to get you started.
EDIT
Here is a useful link with pre-defined macros for common C/C++ compilers.

C Preprocessor testing definedness of multiple macros

I searched the site but did not find the answer I was looking for so here is a really quick question.
I am trying to do something like that :
#ifdef _WIN32 || _WIN64
#include <conio.h>
#endif
How can I do such a thing? I know that _WIN32 is defined for both 32 and 64 bit windows so I would be okay with either for windows detection. I am more interested in whether I can use logical operators like that with preprocessor directives, and if yes how, since the above does not work.
Compiling with gcc I get :
warning: extra tokens at end of #ifdef directive , and it basically just takes the first MACRO and ignores the rest.
Try:
#if defined(_WIN32) || defined(_WIN64)
// do stuff
#endif
The defined macro tests whether or not a name is defined and lets you apply logical operators to the result.
You must use #if and special operator defined
I think it should be possible this way:
#if defined block1 || defined block2 /*or any other boolean operator*/
/*Code*/
#endif
More information here
Use defined:
#if defined(A) || defined(B)
#include <whatever.h>
#endif

Resources