GCC macro with variable number of argument

#define pr(a, b...) printf(a, b) /* (*A) */
#define pr(a, b...) printf(a, ##b) /* (*B) */

pr("Hello\n"); /* (*1) */
pr("Hello %s\n", "World"); /* (*2) */ 
pr("Hello %s %s\n", "My", "World"); /* (*3) */

Above two kinds of macros looks like same at first look. But, there is difference.
In case of (*2) and (*3), (*A) and (*B) both work well.

In terms of (*1), it doesn't have second arguement. That is, it doesn't have arugment 'b'.
So, let's guess result of preprocessing.
Logically, in both case - (*A) and (*B) - "printf(a, )" should be a result, and GCC should complain about this syntax.
But, actual result is, (*A) doesn't work, but (*B) works well.

I didn't check GCC Spec. for this case but, it's interesting enough to leave post :-).

[C/C++/JAVA] 변수를 block중간에 선언하는 방법에 대한 단상.

변수는 사용하기 직전에 선언하는 것이 원칙인데.. 문제는 scope다.
C/C++/JAVA에서 명시적으로 ‘{ }’를 통해서 scope를 잡아주지 않으면, 이후에도 계속 해당 변수가 살아있는 상태가 되어서 좋지 못하다.
그래서 ‘{ }’를 사용해서 scope를 제한해 주는 것이 좋은데, 그렇게 하면, indentation에서 괜시리 한칸 들여쓰여지게 되어 미관상 – 개인적으로 – 마음에 안든다…
음…
변수의 scope를 위한 이~~쁜~~ syntax가 있었으면 좋았을텐데… 라는 생각이 그냥 들어서…

[SW] 확~ 다가오는 각종 명언들…

<출처를 기억할 수 없는 것은 생략했습니다. 혹시 문제가 되는 부분이 있다면 알려 주시기 바랍니다.>

  • 좋은 코드는 변경하기 쉽고, 나쁜 코드는 변경하기 어렵다. 그러므로 좋은 코드는 나쁜 코드가 될 때까지 변경된다.
  • “Provide mechanism not policy” : about interface design. (From the UNIX)
  • 또 뭐가 있지??? — 당장은 생각이 안나는 관계로…

[C/C++] enable/disable function/macro with define switch.

There are two simple examples for this.

#ifdef A
#define xxx(...) BBBB(__VA_ARGS__)
#else
#define xxx(...)
#endif

vs.

#ifdef A
#define xxx(...) BBBB(__VA_ARGS__)
#else
static inline void xxx(){}
#endif

I preferred the second one because at the first case, sometimes unexpected problems are issued. (Just personal opinion/preference...)

[C/C++] Fail to build Android with g++/gcc-4.6 (Ubuntu-11.10)

[ g++ issue ]

g++-4.4 / g++-4.5 doesn’t detect following case, but, g++-4.6 does.

< a.cpp >
---------

class P {
public:
    void a();
};

class A : public P {
public:
    void p();
};

void
P::a() {
    // 'const' quailifier' is discard here!
    static_cast<const A*>(this)->p();
}

void
A::p() {
    ;
}

int
main() {
    return 0;
}

=================== Test ======================
$ g++-4.5 a.cpp   <= OK.
$ g++-4.6 a.cpp
a.cpp: In member function ‘void P::a()’:
a.cpp:13:33: error: passing ‘const A’ as ‘this’ argument of ‘void A::p()’ discards qualifiers [-fpermissive]

The problem is some of Android codes still have above bugs in its code – ex. frameworks/base/libs/utils/RefBase.cpp.
So, even if Android source code was successfully compiled at g++-4.4 or g++4.5, it may be failed at g++-4.6 (for example, upgrading host OS)

[ cc/gcc issue ]

Compiling with gcc-4.6 raises following warings.

<command-line>:0:0: warning: "_FORTIFY_SOURCE" redefined [enabled by default]

In some component which uses ‘-Werror’ option, this warning stops compilation.

[ Conclusion ]

So, you would better to use gcc/g++-4.4 instead of 4.6 when building Android, until above issues are resolved on Android baseline.
(ex. Ubuntu 11.10 as an Android host OS.)

[Linux][Shell] Cleaning PATH environment variable.

With using terminal for a long time, PATH variable tends to be longer and longer due to duplicated path.
Here is simple sample script – with Perl – to resolve this.

# remove duplication at give PATH-format-string
unique_path() {
perl -w -e '
    my %path_hash;
    exit unless (defined $ARGV[0]);
    foreach $p (split (/\:/, $ARGV[0])) {
        unless (defined $path_hash{$p}) {
            $path_hash{$p} = 1;
            push @newpath, $p;
        }
    }
    print join ":", @newpath;
' $1
}
...(skip)...
PATH=$(unique_path "$PATH")
...(skip)

Done :-).

[Android] Developing Android-native-library on 64bit build machine

Most Android device is 32bit machine. So, many application assumes that host machine is 32bit system.
And in general, there is no difference developing Android-natvie-library between 64bit and 32bit build machine.

But, here is usual step for developing Android-native-library.
(1) Developing and verifying code at build machine.
(2) Porting to NDK build system.

Most developers turns on full-warning-option at compile to detect bugs at early stage.
But, building and verifying codes assuming 32bit host machine at 64bit machine always issues type casting warning due to different type size.
Especially, between pointer and integer.

For example, many Android JAVA application uses intjint – as a type to contain native pointer with assumption of 32bit-host-system.
Building this code at 64bit build system to verify code issues type casting warning, even if code itself is built perfectly at NDK build system.
And it is worse that this code doesn’t work at 64bit Android host machine, even though it is not popular.

To reduce this warnings (for easy-verifying of library code at build machine), in my opinion, using longjlong – instead of jint as a type for containing native pointer is better unless memory space is extremely critical.
And to make compiler be happy, using macro can be a good choice.
Here is example of macro for type-casting between pointer and integer – jlong.
(This sample works well without warning at 32bit/64bit build/host system).

#define ptr2jlong(v) ((jlong)((intptr_t)(v)))
#define jlong2ptr(v) ((void*)((intptr_t)(v)))

This is just simple example for portability issues.
Making portable code is always very difficult…

[C/C++] func() vs. func(void)

In C, func() and func(void) have different function signature.
(But, in C++, these two are same.)

‘func()’ means ‘this function can have any number of arguments (0 ~ infinite)’.
But, ‘func(void)’ means ‘this function doesn’t have argument.’
See following example.

#ifdef CASE1
void func(void); /* (1) */
#else
void func();     /* (2) */
#endif

void
func(int i) {
        ; /* do something */
}

If ‘CASE1’ is defined, compiling this file complains error like “error: conflicting types for ‘func'”.
But, ‘CASE1’ is not defined, this is well-compiled.
Now, you can clearly understand difference.

So, using ‘func(void)’ is better for readibility if ‘func’ really doesn’t have any arguement, instead of just ‘func()’.

*** One more. ***
In C, ‘extern’ for function is default visibility.
So, in function declaration, ‘extern void func(void);’ is exactly same with ‘void func(void);’.
Therefore any of them is OK.
( [ omitting ‘extern’ for simplicity ] vs. [ using ‘extern’ to increase readability ] )
But, default visibility of function depends on compiler.
For portability reason, using macro is usually better instead of using explicit directive – especially at shared library header.
(Ex. ‘EXTERN void func(void)’)

[Android] Creating minimum set of Android (Kernel + adbd + ueventd) for Android kernel test.

To test Android kernel, keeping minimum number of user space process is very useful.
Actually, ‘adbd’ and ‘ueventd’ is enough on Android.
Here is the way how to make device have only minimum user space processes – adbd and ueventd.
Followings are file structure of ramdisk image.

[ Create ramdisk ]

let’s make following directory structure in ramdisk.

/bin -> sbin
/sbin -+- busybox
       +- adbd
       +- ueventd -> ../init
       +- <...> -> busybox
/init
/init.rc
/default.prop

All are same with default android except that busybox is in /sbin and /bin is symbolic link to /sbin.
Let’s look into one by one.

/init : same binary with default Android.
/bin : symbolic link to /sbin.
/default.prop : same with default Android. – adb and debugging is enabled.
/sbin/busybox : statically linked busybox.
/sbin/… : tools (symbolic link to busybox). Ex, sh -> busybox, ls -> busybox.
/sbin/adbd :
Modified adbd. Original adbd uses /system/bin/sh as its terminal shell. But, this one uses /bin/sh.
To do this, value of SHELL_COMMAND at system/core/adb/service.c should be modified.
/init.rc :
Simplified one. Only adbd and ueventd is started.
One important note is, “DO NOT make empty section(ex. on fs)!”. This will lead init process to error and system will restarted again and again.
Here is sample.

on early-init
    start ueventd

on init
    sysclktz 0
    export PATH /bin:/sbin:

#on fs

#on post-fs

#on post-fs-data

on boot
   start adbd

## Daemon processes to be run by init.
##
service ueventd /sbin/ueventd

service adbd /sbin/adbd

[ Make ramdisk image ]

Let’s assume that current working directory is ramdisk directory.

find . | cpio -o -H newc | gzip > newramdisk.gz

This newly generated gzip file can be renamed directly to ramdisk.img.

[ Make boot image ]

mkbootimg tool is used. This can be easily found at out/host/<arch>/bin after building android from source.

mkbootimg --cmdline 'no_console_suspend=1 console=null' --kernel <zImage file> --ramdisk <ramdisk image> -o newboot

[ Verify ]

After flashing newly generated boot image, reboot device.
The only respond that device can do, is done at boot-loader stage. After that device doesn’t anything.
After waiting some moments, try adb device. Then host PC can find the device and adb shell can be used.
Type adb shell ps. Then, you can check that only three user space process are running – init, adbd and ueventd.

[ Debugging ]

Except for kernel, adbd and init may be required to be modified (As mentioned above, modified adbd is used.). Printing log is very helpful for debugging and using framebuffer console is simple way to do this.
Here is the step (ex. adbd).

* comment out xxxx in init.c
=> this removes /dev/console (framebuffer console)
* modify start_logging() and start_device_log() in adb.c.
=> use /dev/console as stdout and stderr file.

Now, log message of adbd will be shown on the framebuffer (that is, displayed at the panel.)

[ Something more ]

You may build your own Linux environment on the device by building file system and installing libraries etc.
In my case, I set up tools for development – ex. glibc, gcc, binutils etc, and compiled LTP(Linux Test Project) to test kernel.
Enjoy your minimum Android environment :-).