C:Writing Portable C Code

From GPWiki

Files:GUITutorial_warn.gif The Game Programming Wiki has moved! Files:GUITutorial_warn.gif

The wiki is now hosted by GameDev.NET at wiki.gamedev.net. All gpwiki.org content has been moved to the new server.

However, the GPWiki forums are still active! Come say hello.

This is a small example of a portable C source & header.

example.h

/* Some, very few, compilers might interpret:
 *   #define EXAMPLE_H
 * to be false when calling #ifndef EXAMPLE_H after.
 */
#ifndef EXAMPLE_H
#define EXAMPLE_H 1
 
/* Always use multiline-comments.
 * Single-line C++ style comments arrived in the C99 standard.
 * It is also common to write multiline-comments that span
 * across multiple lines like this one is.
 */
 
/* __STDC__ is defined in C89 (ANSI-C).
 * If we are using a pre-ANSI C compiler then declare a small macro that allows us
 * to skip argument declaration for prototypes.
 */
#ifdef __STDC__
# define __(proto) proto
#else /* __STDC__ */
# define __(proto)
#endif /* __STDC__ */
 
/* We avoid any *_t (uint32_t, ...) datatypes since they are declared in the C99 standard
 * <stdint.h>.
 * Note the extra parenthesis. That is to avoid the pre-compiler to separate the  argument data-types. 
 * It is not needed (sometimes preferred) to have any named arguments in the prototype declaration.
 */
int example_function_one __((int, unsigned char));
unsigned long int example_function_two __((char *));
 
#endif /* EXAMPLE_H */ 

example.c

/* Usually one would use some form of automated configuration and build process
 * to see what libraries and headers that are available in the system (e.g. GNU autotools).
 * The automated system can generate a C header-file with pre-compiler definitions
 * that allows us to see what is available.
 */
 
/* HAVE_CONFIG_H is passed at the command-line by the autotools. */
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
 
/* Include stdio.h if it was found. Otherwise we need to implement the functions that we used from it. */
#if HAVE_STRING_H
# include <string.h>
#endif
 
#include "example.h"
 
/* K&R style declaration, most portable.
 * > C89 allows: int example_function_one(int my_int, unsigned char my_uchar)
 */
int example_function_one(my_int, my_uchar)
  int my_int;
  unsigned char my_uchar;
{
  return (my_int * my_uchar);
}
 
/* long == long int */
unsigned long int example_function_two(c_string)
  char * c_string;
{
/* Here is an example where portability plays a role.
 * If we have <string.h> then we use the best available option.
 * Otherwise we implement our own way of handling the problem.
 */
#if HAVE_STRING_H
  return strlen(c_string);
#else
  unsigned long int i;
  while (*(c_string++) != '\0')
    i++;
  return i;
#endif
}