First I define a value.
#import "ViewController.h"
#define SLIDE_TOP 100;
#define SLIDE_BOTTOM -100;
if(distance > SLIDE_TOP){
NSLog(#"TOP");
}
I found same errors
1.
ViewController.m:98:19: Expected ')'
2.
ViewController.m:98:19: If statement has empty body
When you #define something, the preprocessor simply substitutes replacement tokens (everything after the identifier) for the identifier in the source code. So, your if statement looks like this after the preprocessor runs:
if (distance > 100;) {
NSLog(#"TOP");
}
Note that the semicolon after "100" is included. The compiler doesn't expect the statement to end there, because there's an unmatched open parenthesis, so it complains that you're missing a ')'. The fix is to remove the semicolon from the end of the #define statement:
#define SLIDE_TOP 100
Change these
#define SLIDE_TOP 100;
#define SLIDE_BOTTOM -100;
to
#define SLIDE_TOP 100
#define SLIDE_BOTTOM -100
; is not required in define.
Related
#include<stdio.h>
#define engine_exhaust_gas_temperature_raw 100
#define engine_exhaust_gas_temperature_scaled 20
#define Sum(x, y) ( ( x )+ ( y ) )
int main(){
printf("%d",engine_exhaust_gas_temperature_raw);
return 0;
}
I am working on MISRA C Rule 5.4 Macro identifiers shall be distinct for which I need the list of the names of all the macros defined in a C program as strings.
For ex: In the above code I will need:
[ "engine_exhaust_gas_temperature_raw", "engine_exhaust_gas_temperature_scaled", "Sum"]
Is there any way to get this list using clang AST?
I have found that we can use clangs https://clang.llvm.org/doxygen/classclang_1_1Preprocessor.html Preprocessor class to get the iterator to macros but even this is not producing any output for me. I have used it in the below code. What am I missing here?
bool distinct_macro_identifier(CompilerInstance *C_I, ASTContext *Context){
auto st= C_I->getPreprocessor().macro_begin()->getFirst()->getName();
auto x= C_I->getPreprocessor().macro_begin()->first;
llvm::outs()<<x->getName()<<"\n";
auto p= C_I->getPreprocessor().getMacroInfo(x);
p->dump();
return true;
}
You can compile it with this command:
clang++ -E -dM -nostdlib file.cpp
I want to write a configuration file with qmake that #defines a few values. But I cannot simply create variables that contain the hash or pound character (#). Nonworking example:
lines = "/* Autogenerated: do not edit */"
if(foo): lines += "#define MYLIB_WITH_FOO 1"
else: lines += "#define MYLIB_WITH_FOO 0"
write_file(config.h, lines)
The hash starts a comment (inside the string!), so this won't work. How to generate the proper #defines for write_file under qmake?
There's a predefined variable called LITERAL_HASH specially created to deal with this problem.
If this name seems too long you can create one of your own:
H = $$LITERAL_HASH
lines = "/* Autogenerated: do not edit */"
if(foo): lines += "$${H}define MYLIB_WITH_FOO 1"
else: lines += "$${H}define MYLIB_WITH_FOO 0"
write_file(config.h, lines)
The trick is to use $$system() to create the hash character. This example works for me under Windows and Linux:
pound = $$system(printf $$system_quote(\43))
if(foo): lines += "$${pound}define MYLIB_WITH_FOO 1"
else: lines += "$${pound}define MYLIB_WITH_FOO 0"
It is usual on a C or C++ application sources to include a "config.h" header, that is generated by the buildsystem from a template (for instance "config.h.in"). This is available using autotools, and also CMake - see: configure_file(). But what about Qmake?
Here is an alternative using QMAKE_SUBSTITUTES. Another reference.
test.pro
TEMPLATE = app
QT = core
CONFIG += cmdline c++11
VERSION = 1.2.3
FOO = 1
QMAKE_SUBSTITUTES = config.h.in
SOURCES += main.cpp
DISTFILES += config.h.in
config.h.in
/* Autogenerated: do not edit */
#ifndef CONFIG_H
#define CONFIG_H
#define MYLIB_VERSION '"$$VERSION"'
#define MYLIB_BANNER '"Project version $$VERSION created with Qt $$QT_VERSION"'
#define MYLIB_WITH_FOO $$FOO
#endif // CONFIG_H
main.cpp
#include <QCoreApplication>
#include <QDebug>
#include "config.h"
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
qDebug() << MYLIB_BANNER;
if (MYLIB_WITH_FOO) {
qDebug() << "Foo included!";
}
return 0;
}
Output:
Project version 1.2.3 created with Qt 5.12.5
Foo included!
I have several targets and depending on them I need to import headers. I can do this by defining some preprocessor value and then check it with #ifdef, but I'm wondering, if there any way to do something like:
#if TARGET_NAME = "FirstTarget"
#import "SomeHeader.h"
#endif
u can use like below for example,
//Your current target's are defined
#define FIRST_TARGET "FirstTarget"
#define SECOND_TARGET "SecondTarget"
#define THIRD_TARGET "ThirdTarget"
//set which target u want to run
#define TARGET_NAME FIRST_TARGET //SECOND_TARGET //THIRD_TARGET
//use like below
#if (TARGET_NAME == FIRST_TARGET) //or u can directly specify name instead of defining at the beginning
#import "SomeHeader.h"
//other headers
#elif (TARGET_NAME == SECOND_TARGET)
//header to be in second target
#elif (TARGET_NAME == THIRD_TARGET)
// other header
#endif
Edit:
i got it, it gives error because macros doesn't compare variable length values, for more details see this hear .
so in order to work u can change it like below,
//Your current target's are defined, instead of strings give some constant values
#define FIRST_TARGET 1//#"FirstTarget"
#define SECOND_TARGET 2//#"SecondTarget"
#define THIRD_TARGET 3//#"ThirdTarget"
//set which target u want to run
#define TARGET_NAME FIRST_TARGET //SECOND_TARGET //THIRD_TARGET
//use like below
#if TARGET_NAME == FIRST_TARGET
#import "SomeHeader.h"
//other headers
#elif (TARGET_NAME == SECOND_TARGET)
//header to be in second target
#elif (TARGET_NAME == THIRD_TARGET)
// other header
#endif
I've started using CocoaLumberjack and was interested in using their custom log levels feature. They have a handy config available at https://github.com/CocoaLumberjack/CocoaLumberjack/wiki/CustomLogLevels to get you started. I don't know exactly what I want right now, so I left it as is.
Next I set my debug level in my code using this...
static const int ddLogLevel = LOG_LEVEL_DEBUG;
However with this set up it appears only messages of GREATER severity than LOG_LEVEL_DEBUG get presented. Meaning calls to DDLogInfo() and above show up, but not DDLogDebug(). This is also true as I slide upwards. So...
static const int ddLogLevel = LOG_LEVEL_INFO;
...ignores DDLogInfo() and DDLogDebug(), but shows for DDLogNotice() and higher. Surely the expected behavior is to be inclusive of that warning level.
Here's the code deep inside CocoaLumberjack that makes the decision...
for (DDLoggerNode *loggerNode in loggers) {
// skip the loggers that shouldn't write this message based on the logLevel
if (!(logMessage->logFlag & loggerNode.logLevel)) {
continue;
}
dispatch_group_async(loggingGroup, loggerNode->loggerQueue, ^{ #autoreleasepool {
[loggerNode->logger logMessage:logMessage];
}});
}
In my first example, my log level is 111111 (63) and message flag (using DDLogDebug()) is 100000 (32). 63 & 32 is YES, so this fails (with the NOT). So I would think the message would get logged. Moving the log method up to DDLogInfo() which has a message flag of 010000 (16). This is still YES and therefore fails with the NOT, so we get logged. But I see it in this case. Anyone have any experience with this?
I think I've worked it out. In CocoaLumberjack itself, in DDLog.h, the log level flags are defined like so:
#define LOG_FLAG_ERROR (1 << 0) // 0...00001
#define LOG_FLAG_WARN (1 << 1) // 0...00010
#define LOG_FLAG_INFO (1 << 2) // 0...00100
#define LOG_FLAG_DEBUG (1 << 3) // 0...01000
#define LOG_FLAG_VERBOSE (1 << 4) // 0...10000
However, the CustomLogLevels MyLog.h file defines them like so:
#define LOG_FLAG_FATAL (1 << 0) // 0...000001
#define LOG_FLAG_ERROR (1 << 1) // 0...000010
#define LOG_FLAG_WARN (1 << 2) // 0...000100
#define LOG_FLAG_NOTICE (1 << 3) // 0...001000
#define LOG_FLAG_INFO (1 << 4) // 0...010000
#define LOG_FLAG_DEBUG (1 << 5) // 0...100000
Note that it adds an extra FATAL flag, which has the effect of shifting all of the other flags down a place. This is the cause of the issue you were seeing.
if you have custom levels higher than the inbuilt, try initialising with:
[DDLog addLogger: [DDASLLogger sharedInstance] withLogLevel: LOG_LEVEL_CUSTOM];
[DDLog addLogger: [DDTTYLogger sharedInstance] withLogLevel: LOG_LEVEL_CUSTOM];
where LOG_LEVEL_CUSTOM is defined in your MyLog.h as:
#define LOG_LEVEL_CUSTOM (LOG_FLAG_ERROR | LOG_FLAG_WARN | LOG_FLAG_INFO | LOG_FLAG_CUSTOM)
I have a large enum (for the sake of transparency 63 values), and I am now creating a NS_Options bitflag based on that enum. Is there a way that I can write this so that it will be flexible?
The main concerns I have with hardcoding it are:
If I add/remove an enum, I will have to manually add/remove it in my bitflag.
There is a lot of typing to generate these.
My .h file is getting intensely long (because I like to use whitespace and adequate comments)
The only solution I've come up with thus far is:
#define FlagForEnum(enum) 1 << enum
typedef NS_ENUM(NSInteger, ExampleEnum)
{
Value1,
Value2,
...
ValueN
}
typedef NS_OPTIONS(NSNumber, ExampleEnumFlags)
{
Value1Flag = FlagForEnum(Value1),
Value2Flag = FlagForEnum(Value2),
...
ValueNFlag = FlagForEnum(ValueN)
}
This is a barely adequate solution when I remove an enum (at least I get a compile error), and if the enum ordering gets changed, the flags' bitshifted position changes too (not that it truly matters, but it seems comforting). But it doesn't solve the 'this-is-a-lot-of-typing' problem, or the 'what-if-I-forget-to-add-a-flag' problem.
You can use a technique called X Macro
#define VALUES \
VALUE_LINE(Value1) \
VALUE_LINE(Value2) \
VALUE_LINE(Value3)
typedef NS_ENUM(NSUInteger, ExampleEnum)
{
#define VALUE_LINE(x) x,
VALUES
#undef VALUE_LINE
}
typedef NS_OPTIONS(NSUInteger, ExampleEnumFlags)
{
#define VALUE_LINE(x) x##Flag = 1 << x,
VALUES
#undef VALUE_LINE
}
Here is a slightly better (in terms of less typing) preprocessor #define solution. Although this still isn't as elegant as I'd like.
#define BitShift(ENUM_ATTRIBUTE) (1 << ENUM_ATTRIBUTE)
#define CreateEnumFlag(ENUM_ATTRIBUTE) ENUM_ATTRIBUTE##Flag = BitShift(ENUM_ATTRIBUTE)
typedef NS_ENUM(NSUInteger, ExampleEnum)
{
Value1,
Value2,
...
ValueN
}
typedef NS_Options(NSUInteger, ExampleEnumFlags)
{
CreateEnumFlag(Value1),
CreateEnumFlag(Value2),
...
CreateEnumFlag(ValueN)
}
This will create flags of the form Value1Flag, Value2Flag, ..., ValueNFlag.