Invalid preprocessing directive for #elseifdef in Xcode - objective-c

Why:
#ifdef SOME_TARGET_FLAG
<some code here>
#elseifdef SOME_ANOTHER_TARGET_FLAG
<some another code here>
#endif
produces "Invalid preprocessing directive" preprocess compilation error?
SOME_TARGET_FLAG and SOME_ANOTHER_TARGET_FLAG are just some "Other C-flags" defined in target build settings (-D<FLAG_NAME> pattern).
Is #elseifdef directive not supported by Xcode?

Is #elseifdef directive not supported by Xcode?
It is not. Use this instead:
#elif defined(SOME_ANOTHER_TARGET_FLAG)

Its not supported as indicated by the error message. See 'the C preprocessor' - https://developer.apple.com/library/mac/#documentation/DeveloperTools/gcc-4.2.1/cpp/index.html#//apple_ref/doc/uid/TP40007092 (conditional compilation).

Related

How can I define an executable that has different compiler command-line arguments?

I have a C++ project and I want to test the compatibility of library headers with different compiler versions. I have a simple source file (that includes said headers) and I want to change the compiler argument to std=gnu++11 for this one target. How do I do that?
executable('old_compiler_test', ['octest.cxx']
# override ARGS here ??? how
)
Note that I have
add_global_arguments(
['-std=gnu++17',
....
rather than the dedicated option for this, in spite of the warning to prefer the special option, because the special option simply doesn't work. (Why is a question I've never tracked down)
update
To clarify: I'm not trying to make additional configurations in the same way that debug and release are configurations. I want a different compiler argument to be applied to a single target within the configuration.
From the Meson documentation, you can use the argument <languagename>_args to pass additional compiler arguments. In your case, since you use C++, it would give something like
executable('old_compiler_test', ['octest.cxx'],
cpp_args: ['std=gnu++11']
)
However the documentation also specify that there are no way to disable an argument added by add_global_argument(), so you will end up with both -std=gnu++17 and -std=gnu++11 passed to the compiler. I don't know how your compiler will behave, but I tried to pass both arguments to GCC 10.2 and it uses c++17 (not what you want).
Workaround
It seems that if you define the C++ version in the project() statement, Meson will removes it if an other version is specified in compiler arguments, giving the behaviour you expect.
Here is the sample I used:
meson.build
project('project-name', 'cpp',
default_options: ['cpp_std=c++17']
)
executable('old_compiler_test', ['octest.cxx'],
cpp_args: ['-std=gnu++11']
)
octest.cxx
#include <iostream>
int main() {
std::cout << __cplusplus << std::endl;
}
After compilation, running the executable will print 201103, which means that the compiler used c++11 as desired.

OBJC_EXTERN: what's the purpose?

Hi was reviewing some Objective-C code and found out the following statement:
OBJC_EXTERN void CLSLog(NSString *format, ...) NS_FORMAT_FUNCTION(1,2);
What does this mean?
Also, what is supposed to be the syntax of this statement?
Thanks in advance.
OBJC_EXTERN is defined in <objc/objc-api.h> as
#if !defined(OBJC_EXTERN)
# if defined(__cplusplus)
# define OBJC_EXTERN extern "C"
# else
# define OBJC_EXTERN extern
# endif
#endif
and therefore prevents "C++ name mangling" even if the above declaration is
included from a C++ source file, as for example explained here:
In C++ source, what is the effect of extern "C"?
For pure C code, you can just remove the OBJC_EXTERN, because the extern
keyword is not needed in a function declaration.
NS_FORMAT_FUNCTION is defined as
#define NS_FORMAT_FUNCTION(F,A) __attribute__((format(__NSString__, F, A)))
and __attribute__((format(...))) is a GCC specific extension, also understood
by Clang:
http://clang.llvm.org/docs/LanguageExtensions.html#format-string-checking
http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html
It allows the compiler to check the number and types of the variable argument list
against the format string. For example
CLSLog(#"%s", 123);
would cause a compiler warning, because %s is the placeholder for a string,
but 123 is an integer.

How to disable warning: Using 'stringWithString' with a literal is redundant?

Some old third party code gives warning:
Using 'stringWithString' with a literal is redundant
Instead of modifying the source codes, I'd prefer to disable the warning in Xcode. What is the compiler switch to disable this specific warning?
The warning message should tell you the name of the warning. You can then turn that warning off.
test.m:4:5: warning: using 'stringWithString:' with a literal is redundant
[-Wobjc-redundant-literal-use]
so you want to add the flag -Wno-objc-redundant-literal-use to the compiler flags for that file or that project.
One way to do that is :
Select your target .
Go to the compiled sources.
Select your .m file and set flag -w to suppress all the warning of that file .

how to get visual c++ default include path using cmake?

I try to use cmake determine whether exist inttypes.h header file for generate project of visual c++ 11.
Initially, i wrote the following sentence in CMakeLists.txt
FIND_FILE(HAVE_INTTYPES_H "inttypes.h" DOC "Does the inttypes.h exist?")
Unfortunately, the HAVE_INTTYPES_H variable is HAVE_INTTYPES_H-NOTFOUND.
Afterwards, i looked up cmake documentation about find_file, which mentioned the need to some search path. But i can not get the c standard header files in any place in cmake?
Thanks.
Your find_file call is correct. The problem is there's no inttypes.h on Visual Studio. So keep your test the same, but when it's not found include another headers, for instance provided by: http://code.google.com/p/msinttypes/
Something like:
FIND_FILE(HAVE_INTTYPES_H "inttypes.h" DOC "Does the inttypes.h exist?")
if (HAVE_INTTYPES_H)
add_definitions(-DHAVE_INTTYPES_H=1)
endif()
and in your code:
#ifdef HAVE_INTTYPES_H
#include <inttypes.h>
#else
#include "path/to/inttypes.h"
#endif
Now, to detect headers, you may also want to try using the CheckIncludeFile standard CMake module, it's trying to detect include files using your target compiler instead of searching the file system:
include(CheckIncludeFile)
check_include_file("stdint.h" STDINT_H_FOUND)
if (STDINT_H_FOUND)
add_definitions(-DHAVE_STDINT_H=1)
endif()

Xcode #ifdef DEBUG is not working properly

I have add following line to the code.
#ifdef DEBUG
//DEBUG only code
#endif
And I have go to the project->info tab in the xcode and set 'command-line builds use' to debug and run the code the code snippet inside the 'if' executed. The problem is when i set the command-line build' use to release and run the code. The code snippet inside the if condition still runs. I have set the preprocessor DEBUG macros to 'DEBUG=1'without quotes. How to solve this.
The #ifdef syntax means "is defined", without regard to value; in other words, it is defined if it has any value at all (0 or 1).
You probably want the #if syntax instead. This requires that the value actually be set to 1.