I understand how to use a preprocessor directive like this:
#if SOME_VARIABLE
// Do something
#else
// Do something else
#endif
But what if I only want to do something IF NOT SOME_VARIABLE.
Obviously I still could do this:
#if SOME_VARIABLE
#else
// Do something else
#endif
. . . leaving the if empty, But is there a way to do:
#if not SOME_VARIABLE
// Do something
#endif
Apple documentation here suggests not, but this seems like a very basic need.
Basically I want to do the preprocessor equivalent of:
if(!SOME_VARIABLE)(
{
// Do Something
}
you could try:
#if !(SOME_VARIABLE)
// Do something
#endif
Are you trying to check if something is defined or not?
If yes, you can try:
#ifndef SOME_VARIABLE
or
#if !defined(SOME_VARIABLE)
The Apple documentation (If - The C Preprocessor) is correct and this is the way that C pre-processor statements have been since the dawn of time. As per that same documentation all you can do is craft an expression that evaluates to either zero or a non-zero value and use that.
Meccan's answers is correct as TARGET_IPHONE_SIMULATOR is defined as TRUE or FALSE depending on the platform, so the expression will evaluate to either zero or a non-zero amount.
In general these macros (#if etc) are used for including or excluding things based on whether a symbol is defined or not. For that use case the pre-processor has #ifdef and #ifndef which covers what has historically been accepted as the most important cases.
Also given that the subject of these statements can only be other pre-processor defined symbols (via #define) then this limitation is reasonable.
Related
I would like to do something like:
DEFAULT_CLUSTER_ALIASES = {
"local": "$(DEFAULT_LOCAL_CLUSTER)",
}
def helm_action(**kwargs):
if not "$(DEFAULT_LOCAL_CLUSTER)":
DEFAULT_LOCAL_CLUSTER = "docker-desktop"
_helm_action(
cluster_aliases = DEFAULT_CLUSTER_ALIASES,
**kwargs
)
IOW, if DEFAULT_LOCAL_CLUSTER is not defined, DEFAULT_CLUSTER_ALIASES will be dict("local": "docker-desktop").
and if --define=DEFAULT_LOCAL_CLUSTER=minikube, DEFAULT_CLUSTER_ALIASES will be dict("local": "minikube").
So far, I haven't been able to get the Make variable to be evaluated and DEFAULT_CLUSTER_ALIASES is dict("local": "$(DEFAULT_LOCAL_CLUSTER)").
What's needed so the Make variable is evaluated?
"make variables" are only evaluated in the context of rule attributes that support make variable substitution. See https://bazel.build/reference/be/make-variables#use
If helm_action is a macro, or is used from a macro, then this won't work because macros don't have access to configuration information (e.g. values from flags). If helm_action is used from a rule implementation, then you can access values set using --define from ctx.var: https://bazel.build/rules/lib/ctx#var
Another way to do this is to use Starlark flags: https://bazel.build/rules/config#user-defined-build-settings Though again, it depends on if you're writing a macro or a rule.
I am looking for preprocessor directive to disable compiler warnings for desired block of code in MQL4.
I have some bitwise IFs and don't want to cast everything explicitly like:
if ( (bool)(flag & 0x00110101) ) {}
Instead I am looking for something like:
#nowarn
if ( flag & 0x00110101 ) {}
We are currently using the Microsoft.VisualStudio.TestTools.CppUnitTestFramework which defines test classes with a macro, ex:
TEST_CLASS(Class1)
{
public:
TEST_METHOD(Method1)
{
Logger::WriteMessage("In Method1");
Assert::AreEqual(0, 0);
}
};
I am having a hard time getting clang-format to "understand" that TEST_CLASS is a struct/class definition. After trying a couple of things the current best solution I got is to define two new macros to wrap the class:
#define START_TEST(className) TEST_CLASS(className){
#define END_TEST };
and define them as a block start/end:
MacroBlockBegin: ^START_TEST.*$
MacroBlockEnd: ^END_TEST.*$
I am wondering if there is a better solution that does not involve adding more macros...
The method I am trying to call is;
- (void)addLogWithLevel:(MDCLogLevel)logLevel logContent:(NSString *)logContent, ...
{
va_list args;
va_start(args, logContent);
NSString *message = [[NSString alloc] initWithFormat:logContent
arguments:args];
va_end(args);
MDCLog *log = [MDCLog logWithContent:message content:logLevel];
[self.deviceLogs addObject:log];
}
I have defined the macro as;
#define MDCLogDebug(format, ...) [[MDCLogController sharedController] addLogWithLevel:MDCLogLevelDebug logContent:(__VA_ARGS__)];
I have tried various formats of this macro, but nothing seems to work.
If I am to call;
MDCLogDebug(#"Test:%#", #"Hey");
All I see in the console is;
Hey
Where am I going wrong? I'm new to using Variadic methods and my C isn't so great!
Actually, your problem is not really related to Objective-C directly, but to C itself, as macros are plain C preprocessor directives.
In a macro, __VA_ARGS__ represents the arguments that are placed instead of the ....
So in your call to MDCLogDebug(#"Test:%#", #"Hey"), the format argument is #"Test:%#" and __VA_ARGS__ represents the rest of the arguments afterwards, namely simply #"Hey" in your case.
If you want to pass both the #"Test:%#" and #"Hey" as arguments to logContent:, you have to explicitly tell it so, using:
#define MDCLogDebug(format, ...) [[MDCLogController sharedController] addLogWithLevel:MDCLogLevelDebug logContent:format, __VA_ARGS__]
Note: An even better solution would be to use the ## prefix before __VA_ARGS__ so that the comma won't be added if __VA_ARGS__ is empty (namely if you only pass a format argument but nothing afterwards, like MDCLogDebug(#"Foo")):
#define MDCLogDebug(format, ...) [[MDCLogController sharedController] \
addLogWithLevel:MDCLogLevelDebug \
logContent:format, ## __VA_ARGS__]
(Note: I use backslashes in this last macro definition above to allow the macro to be written on multiple lines, instead of writing it on one single big long line)
For more information, see the official GCC documentation about Variadic Macros here.
There are 3 (which I know) ways to suppress the "unused variable" warning. Any particular way is better than other ?
First
- (void)testString:(NSString *)testString
{
(void)testString;
}
Second
- (void)testString:(NSString *)__unused testString
{
}
Third
- (void)testString:(NSString *)testString
{
#pragma unused(testString)
}
This is the approach I use: cross platform macro for silencing unused variables warning
It allows you to use one macro for any platform (although the definitions may differ, depending on the compiler), so it's a very portable approach to express your intention to popular compilers for C based languages. On GCC and Clang, it is equivalent of wrapping your third example (#pragma unused(testString)) into a macro.
Using the example from the linked answer:
- (void)testString:(NSString *)testString
{
MONUnusedParameter(testString);
}
I've found this approach best for portability and clarity, in use with some pretty large C, C++, ObjC, and ObjC++ codebases.
If you are compiling with GCC, you can take advantage of attribute extensions to set the 'unused' attribute. Like this:
int somevar __attribute__((unused));
It also works for unused parameter warnings (-Wunused-parameter)
To make it shorter to write I am using this macro:
#define _U_ __attribute__((unused))
And declare like this:
int somevar _U_ ;
One way to do it is just to assign a variable pointlessly after it is declared For example:
int foo;
foo = 0;
This should suppress the unused variable warning. It is just a pointless assignment.
But otherwise I would agree with ouah, the first method is the most reliable, if you must choose from those three.