When I read the source code of google glog, I found the following macro confusing to me:
#define LOG_IF(severity, condition) \
static_cast<void>(0), \
!(condition) ? (void) 0 : google::LogMessageVoidify() & LOG(severity)
What's the meaning of static_cast<void>(0),?
What's the meaning of & in the third line?
What does the result look like if we expand this macro?
I'm new to c++. Thank you all for the help!
Related
I have the following macro in a logging library of mine :
#define TRACE_E(__logCat,__format,...) \
do { \
::dbg::LogCategory * const __catPtrVal = (::dbg::LogCategory *)(__logCat); \
if( NULL != __catPtrVal && __catPtrVal->IsEnabled() ) \
{ \
__catPtrVal->Error( __format, __VA_ARGS__ ); \
} \
} while( false )
Under Visual Studio (2008) it works as intended, i.e i can do both TRACE_E( pLog, "some message without parameters" ); and TRACE_E( pLog, "some message with parameters %d %d", 4, 8 );
But when using this same library with eclipse and the Android NDK i'm getting a compilation error if i don't pass at least one parameter after the format string in my macro, i.e TRACE_E( pLog, "some message without parameters" ); is not valid, but TRACE_E( pLog, "some message without parameters", 0 ); is, which forces me to pass a dummy parameter when none is needed.
Is there any difference of behaviour with variadic macros when using g++ rather than Visual Studio's compiler ? Thank you.
Yes. What you are attempting is not possible in standard C or C++.
This is arguably a defect in the respective standards for which different compilers have different workarounds. Visual Studio tries to make it work as-is, gcc and clang require the following syntax:
__catPtrVal->Error( __format, ##__VA_ARGS__ );
This is described here for gcc; clang just adopted gcc's way of doing things. Unfortunately, MSVC does not understand this syntax. There is, to my knowledge, no portable way of solving this in the general case.
For your particular macro, though, you could simply write
#define TRACE_E(__logCat,...) \
do { \
::dbg::LogCategory * const __catPtrVal = (::dbg::LogCategory *)(__logCat); \
if( NULL != __catPtrVal && __catPtrVal->IsEnabled() ) \
{ \
__catPtrVal->Error(__VA_ARGS__ ); \
} \
} while( false )
Since the only place where you use __format is directly before __VA_ARGS__.
Side note: You're using a lot of reserved identifiers there. Unless you're writing a standard library implementation, you should go easier on the underscores.
BACKGROUND:
I'm following a tutorial online: Game apps in Android by Todd Perkins
- It's been very straightforward other than the hiccups that come with setting up NDK with eclipse, which I've managed to solve.
Problem:
I'm stuck at the point where I want my cocos2dx code to respond to a touch event and based on that, call Java android code from an activity.
I've added a bunch of screen shots below to show you how I've set everything up:
When I run build_native.sh:
Now I've made sure that I've linked my folders correctly in the project.
Below is a screen shot of the "linked" JNI folder(jni_linked), along with JniURL.cpp and JniURL.h:
and here's what my Android.mk file looks like:
I've double/triple checked the path of my Jni folder and it is:
C:\Users\DarkRaveDev\Documents\cocos2d-x-2.0.1\cocos2dx\platform\android\jni
Do I need to change the Android.mk file to have this line:
LOCAL_SRC_FILES := helloworld/main.cpp \
../../Classes/AppDelegate.cpp \
../../jni_linked/JniURL.cpp \
../../Classes/HelloWorldScene.cpp
It's probably treating:
/../../../cocos2dx/platform/android/jni/JniURL.cpp \
as starting with an absolute path instead of a relative path. It probably should be:
$(LOCAL_PATH)/../../../cocos2dx/platform/android/jni/JniURL.cpp \
or maybe:
../../../cocos2dx/platform/android/jni/JniURL.cpp \
In CPP code, for ex in camera HAL, ALOGD messages are not being printed.
Like in set_preview_window()
ALOGD("set_preview_window : X, rc %d", rc);
How to enable them?
try to add following statements in the files which you wanted to catch logs.
#define LOG_NDEBUG 0
#define LOG_NIDEBUG 0
#define LOG_NDDEBUG 0
After compiled, you can try to get logs through adb logcat.
These macros (ALOGX...) are defined in some system core C/C++ headers.
You can find an example in system/core/include/log/log.h (AOSP 6.0.0r1)
Sometimes you need to add liblog in LOCAL_SHARED_LIBRARIES of the corresponding Android.mk :
LOCAL_SHARED_LIBRARIES := ... liblog
Also, you might need to add two lines at the top of C/C++ concerned source files :
#define LOG_NDEBUG 0
#define LOG_TAG "LibName"
Don't forget LOG_NDEBUG 0 if you want ALOGV() logs.
After rebuilding the lib/module, you should be able to see logs in your logcat.
See the definition of ALOGD to get a hint.
In my case i had to do
setprop persist.testapp.debug.log 5
5 was debug level.
To get logs from CPP to Android you ca use the following
__android_log_print(ANDROID_LOG_ERROR, "TRACKERS", "%s", Str);
and to use this you need to import the following library
#include <android/log.h>
if you Want o get simple logs you ca use the following
LOG("Add description here");
I am building ffmpeg and stuck in an unusual spot. Inside libavutil we have float_dsp.h and float_dsp.c files. Inside these file there is a declaration of a methond which is:
void (*butterflies_float)(float *av_restrict v1, float *av_restrict v2, int len);
float (*scalarproduct_float)(const float *v1, const float *v2, int len);
when building and compiling this file i get this error and have no idea what to do. I think problem is somewhere else but again have no idea at all. Error is
jni/ffmpeg/libavcodec/../libavutil/float_dsp.h:150: error: expected ';', ',' or ')' before 'v1'
jni/ffmpeg/libavcodec/../libavutil/float_dsp.h:161: error: expected ';' before 'float'
Anybody who wants to help please take a step forward because i have not really got any support on ffmpeg during couple of weeks now.
Regards
This may be caused by:
not set GCC to C99 mode where restrict keyword is supported
restrict was redefined by some #define
restrict is not supported for particular architecture but this is unlikely
GCC is set to C++ mode where restrict keyword is not supported GCC according http://gcc.gnu.org/onlinedocs/gcc/Restricted-Pointers.html.
There are other supported forms by GCC like __restrict and __restrict__.
ffmpeg configure script sets macro av_restrict to just restrict which can be checked in produced config.h file.
Fix could be to change configure detection code and remove invalid case restrict:
--- ./configure.orig 2014-01-15 18:53:59.000000000 +0100
+++ ./configure 2014-03-13 17:50:45.754442028 +0100
## -3896,7 +3896,7 ##
EOF
_restrict=
-for restrict_keyword in restrict __restrict__ __restrict; do
+for restrict_keyword in __restrict__ __restrict; do
check_cc <<EOF && _restrict=$restrict_keyword && break
void foo(char * $restrict_keyword p);
EOF
I'm compiling a nexus one android kernel from source as found on HTCs developer website. I've obtained an ARM tool chain by DLing the android NDK from the android dev site. I am able to run make clean and make defconfig without incident, but when I run make, it only gets so fare before running into compiler errors.
Currently i see the following:
$MY_DIR/nexus_one/arch/arm/include/asm/glue.h:156:29: error: '#' is not followed by a macro parameter
The offending line is:
1 /*
2 * Instruction Fault Status Register. (New register as of ARMv6)
3 * If processor has IFSR then set value, else set translation fault
4 */
5 #if defined(CONFIG_CPU_ABRT_EV7) || defined(CONFIG_CPU_ABRT_EV6)
6 # define CPU_PABORT_IFSR(reg) mrc p15, 0, reg, cr5, cr0, 1 #asm macro;
7 #else
8 # define CPU_PABORT_IFSR(reg) mov reg, #5 #asm macro;
9 #endif
Specifically, line 8 above is what hoses the compiler. Apparently you can't have that second # sign, but i'm not really sure whats going on in this code, and it looks pretty important so i don't want to touch it.
I'm guessing i'm compiling with the wrong tool chain maybe? Or perhaps i have configured things wrong somehow? Does any one have any idea what this is all about?
thanks,
brian
I strongly recommend you to use CodeSourcery toolchain for Linux for compiling Linux kernel.
CodeSourcery GNU Toolchain for ARM Processors: 2008q1-126 version
Turns out it was nothing to do with the specific toolchain. The # sign needed 'escaping' of some sort. The solution was as follows:
/* this is needed to get the mov reg, 5 macro to compile and function correctly */
#define hash_hackery #
#define f(x) x
#if defined(CONFIG_CPU_ABRT_EV7) || defined(CONFIG_CPU_ABRT_EV6)
# define CPU_PABORT_IFSR(reg) mrc p15, 0, reg, cr5, cr0, 1 #asm macro;
#else
# define CPU_PABORT_IFSR(reg) mov reg, f(hash_hackery)5 #asm macro;
#endif
This post was very informative in finding the answer.