Introduction

The world is bigger than just Linux, i386 and the GNU C Compiler. Here are some common pitfalls and how you can prevent them.

ISO C99

The recent C99 standard provides a number of useful additions to the language, but not all platforms have adopted the new standard yet and still ship with a C89 compiler. For code to be portable to those platforms, the new features found in C99 can't be used.

If you are using GCC, you can check whether you are using any C99 or GNU features by compiling your application with CFLAGS set to "-pedantic -std=c89" (don't hard code these arguments in your makefile though, since they are GCC specific).

Some C99 features to watch out for are:

1. variable declarations part way through a block:

  • char *s = g_strdup ("hello, world");
    show_message (s);
    size_t i = strlen (s);
    This can be fixed by moving the declaration to the top of the block.

2. C++ style comments. Use the standard /* ... */ form instead.

3. extended structure initialisation:

  • GdkRectangle rect = {
        .x = 0, .y = 0,
        .width = 100, .height = 100
    };

gcc-2.95

The GNU C Compiler allows macros with a variable number of arguments. These are defined as follows:

  #define PRINT(fmt, ...) fprintf(stderr , __VA_ARGS__)

The important point is the whitespace character before the comma. When you pass no additional arguments to the PRINT macro, e.g. PRINT("hello"), the VA_ARGS token and the token before are removed. Now there's a different interpretation of the token before. Gcc-2.95 removes everything upto the next whitespace, whereas later versions only remove the comma.

Autoconf M4 macros

Automake-1.9 often warns about

  • Unquoted definition of GTK_BLA_BLUBB.

To avoid this, write

  • AC_DEFUN([GTK_BLA_BLUBB], ...

instead of

  • AC_DEFUN(GTK_BLA_BLUBB, ...

Rationale: the reason for this is to avoid problems with duplicate definitions of a macro, which can result in weird error messages. For example:

  • AC_DEFUN(FOO, BAR)
    AC_DEFUN(FOO, BAZ)

The above will define the macros FOO -> BAR and BAR -> BAZ, since the first argument of the second AC_DEFUN call gets evaluated to BAR. By quoting the arguments, the error is avoided.

Compiler Warnings

The GNU C Compiler can emit many warnings, most of which are very useful. Don't ignore them. If you don't understand the warnings, post them here, and they will be explained.

If you are using the GNU C Compiler, run

./configure CFLAGS="-Wall -Wwrite-strings"

to get the most useful warnings. There are still more CFLAGS to enable additional warnings, which you can look up in the gcc manpage.

To make sure you don't overlook any warnings, you can add -Werror to the CFLAGS.

You can also use the GNOME_COMPILE_WARNINGS macro from gnome-common.

Shell Scripts

The test(1) command only accepts = as equality operator, not ==. Not even GNU test(1) accepts ==, it's only valid in bash and some implementations of the ksh.

Instead of:

  • if test x"${var}" == x"yes"; then ...; fi

use:

  • if test x"${var}" = x"yes"; then ...; fi

See http://www.opengroup.org/onlinepubs/009695399/utilities/test.html for details.

AM_GLIB_DEFINE_LOCALEDIR

Don't use this autoconf macro. It is broken by design and does not follow the GNU Coding Standards. See http://www.gnu.org/software/autoconf/manual/html_node/Defining-Directories.html for doing it the right way.


CategoryDeveloperTutorial

WritingPortableCode (last edited 2013-07-26 15:00:04 by SébastienWilmet)