Schlagwort-Archive: macros

Portable __VA_ARGS__ macros for Linux, HP-UX, Solaris and AIX

I recently needed a macro with variable arguments that work on all mainstream compilers. I use gcc only on Linux, on the other platforms I want to use the „native“ compiler that belongs to the OS. Let’s start with Linux.

Linux

If you’re inside the gnu/gcc world, things are easy. This is what everybody tries first:

The problems start, if you want to use the macro without variable arguments.

gcc will not accept the code, because it resolves the macro to

(note the comma)

The gcc workaround for this kind of a situation is:

If „s“ is null, this erases the comma to the left of the „##“ in the macro definition. The resulting expansion is:

The comma is gone, the code compiles. Great.

HP-UX

However, this approach fails on HP-UX

I found the solution for this problem in the HP-docs:

you must insert a space to the left of the comma to make it clear to the preprocessor that the comma is the left operand of the „##“ operator.

Yes. A space. Left of the comma. Sigh….

The definition that works on Linux and HP’s cc -AC99 compiler looks like this:

Solaris

Solaris c89 compiles the above definition with a warning:

Solaris c99 compiler is very strict and allows

only. The documentation points out, that it is possible to use #__VA_ARGS__ which seems to be similar to GNU’s/HP’s ## Operator:

Ok, the code compiles, but calling PRINTERROR results in a „argument mismatch“-warning. I found no other solution than disabling the warning. Dirty but it works:

If course it is bad to hide warnings, but if your code is multi-platform, you can use very strict compiler settings on another platform to make the warnings visible at least there.

AIX

The original AIX-compiler (cc) does not complain, but c89 fails with

There is a langlvl #pragma to switch the compiler language level. All levels that allow implementation-specific language extensions are sufficient. I used extc99 which allows to use the c99 compiler. Simply add this to the beginning of your sourcefile:

The final result

This is the result of some hours browsing the compiler docs. The macro works on all c99-compilers mentioned above and allows zero arguments:

Of course you have to use the compiler switch -D_AIX, -D_SOLARIS or -D_HPUX on the apropriate platform. Let me know what do you think and how it could be done better.

Update: André suggests this solution (see his comment):