What does gcc #define when compiling objective-c(++)? - objective-c

Is there some #define I can look at so that I know when to pull in <OpenGLES/EAGL.h>, for instance? Thanks!

This should work:
#if defined(__OBJC__) && defined(__cplusplus)
For Objective-C just leave off the __cplusplus part

You should be able to determine this by running "gcc -v filename" and looking for the arguments to the "cc1" command (-DTHIS, -DTHAT, ...).

Related

#if macros in Objective-C

I am trying to define the value of a macro based on some condition like
#define DEV NO
#if DEV == YES
#define API_ENDPOINT_HOST #"https://my-dev.com/"
#else
#define API_ENDPOINT_HOST #"http://my-qa.com/"
#endif
But even though I have defined DEV as No, it is always taking API_ENDPOINT_HOST as #"https://my-dev.com/". What is wrong here?
Even Uli's answer is correct (as everyone expected), I want to explain it in more detail:
In PP phase an undefined identifier in an #if directive is replaced with 0. NO and YES are not defined anymore as macro as it has been in the past, but became literals. So they are undefined in PP phase.
Your second line is:
#if DEV == YES
DEV is replaced with NO …,
#if NO == YES
… what is undefined as YES is. Therefore both are replaced by 0:
#if 0 == 0
That's obviously true.
NO and YES are Objective-C constructs. The preprocessor runs before the Objective-C compiler, so does not know YES or NO yet. Usually people use 0 and 1 in preprocessor defines.
Alternatively, just define your symbol and then use #ifdef instead of #if.
#define DEV
#ifdef DEV
#define API_ENDPOINT_HOST #"https://my-dev.com/"
#else
#define API_ENDPOINT_HOST #"http://my-qa.com/"
#endif

how to add lines to source code at compiling but keeping it intact

I want to compile source codes but I need to add extern "C" to a lot of header files from other package. So I have to keep those intact at the same time.
What I am wondering is, can I add
#ifdef __cplusplus
extern "C" {
#endif
at the header and
#ifdef __cplusplus
}
#endif
to the footer for every header I am interested in?
What I can think of is passing those files to the compiler using $awk but I cannot come up with the details.
Is there any known examples or something I can dig in?
Thank you very much.
You can create wrappers instead that include the headers in question like this:
extern "C" {
#include "header.h"
}
In your own code, you then include the wrappers, not the original headers.
You can automate the creation of those wrapper headers with a one-time script, which should be straightforward. In Bash, for example, I'd just do something like:
for f in include/*; do echo -e "extern \"C\" {\n#include \""$f"\"\n}" > "include_wrappers/wrap_$f"; done

Does "clang" perform common subexpression elimination?

I try do compile my opencl kernel to llvm IR.
With the following instruction
/home/mypass/llvm/Debug+Asserts/bin/clang -I/home/ian031545/libclc/generic/include -include clc/clc.h -Dcl_clang_storage_class_specifiers -target nvptx--nvidiacl -Xclang -mlink-bitcode-file -Xclang /ian031545/libclc/nvptx--nvidiacl/lib/builtins.bc -S -emit-llvm kernel.cl -o kernel.ll
The opencl kernel's structure look like this
__kernel(){
if() x[i]=a+b+1
else x[i]=a+b+2
}
And the llvm IR after using the instruction above look like this
entry: // it perform a+b here , we say c
then part: // it perform c+1
else part: // it perform c+2
Does anyone know why does clang do this kind of optimization here ? ( we say it frontend )
Or it may not be a kind of optimization ?
I don't know why clang do this here , for what purpose ?
Can i ask clang not to do this by adding flag to the instruction above ?
Thanks in advance
Try using -O0 flag with clang.

Unterminated conditional directive in Xcode

What's wrong here:
#define CONTROLS_OFFSET 100
#ifdef CONTROLS_OFFSET//Unterminated conditional directive it says
#define FIND_MAIN_MENU 3
Why do i get this error?
An #ifdef, like an #if, needs to be balanced by an #endif. In this case, that would probably go immediately after your #define line.
Something like this:
#ifdef DEBUG
NSLog (#"This is a test");
#endif

Is it possible to use #ifdef like checks in assembler?

I have tested a bit of assembler on Linux using the AT&T syntax. One thing that struck me was that the book I was reading was written from a 32-bit standpoint. Thus, all sizes would have to be changed to the correct 64-bit versions for me. Or I could (which I did) assemble the code using the --32 flag for as and the -melf_i386 flag for ld when linking. I have also adapted some of the code and to run on Windows under Cygwin.
But that got me thinking. Is there a way to do ifdef like checks in assembler to do one thing if I'm on Windows and another under Linux and also handle 32 vs 64 bit that way? For example to have a .globl _start under Linux and a .globl _main under Windows.
Or is this handled by checking before assembling and having different source files to assemble based on the result of the checks?
I.e. foo_linux.s and foo_windows.s
If so, how do you overcome that fact that you will not know which .s files you will use, and thus have to include, when you are creating your program?
For example, say that we have a socket_linux.s and a socket_windows.s. They both present an identical interface but do the OS specific work associated to sockets. But when I work with the sockets in my program I will not know if I need the Windows or Linux version included. So I would be kinda screwed :)
So how is this handled in Assembler? In C++ for example I could include my socket.h and socket.cpp and wrap all the Linux and Windows specific code in #ifdef statements.
If you use GCC to compile your files and name them .S (with uppercase S) or .sx, it will pass them through the preprocessor before invoking the assembler.
From the docs:
file.s
Assembler code.
file.S
file.sx
Assembler code which must be preprocessed.
You can add -v to the command line to see how the various sub-processes are invoked.
in MASM (.asm), you can use ifdef, ifndef and the likes, as:
ifdef X64
endif
When writing for different platforms you can define some macro for loading target specific files:
FILE target.h
#if defined(__arm__)
#define target "arm"
#elif defined(__x86_64__)
#if defined(_WIN64)
#define target "win64"
#else
#define target "linux64" // all non-Win share the same calling convention
#endif
#else
// 32bit defs
#endif
Then you can include target specific files with the macro, two string literals successively get one single literal:
#include "target.h"
#include "target_specific_code_" target ".h"
It includes one of these files:
target_specific_code_arm.h
target_specific_code_win64.h
target_specific_code_linux64.h
...
EDIT:
Like this, you can also define target specific assembler instructions for later use in inline assembly:
#ifdef ...
#define ASM_PP_LOAD_WORD "movi "
#else
#define ASM_PP_LOAD_WORD "mov "
#endif
or as macro
#ifdef ...
// when using intel assembler there is a different
// order of parameters
#define ASM_PP_LOAD_WORD(a, b) "movi " #b ", " #a
#else
#define ASM_PP_LOAD_WORD(a, b) "mov " #a ", " #b
#endif