Preprocessor Seam

Introduction

C and C++ offer another possibility to alter the behaviour of code without touching it in that place using the preprocessor. Although we are able to change the behaviour of existing code as shown with object and compile seams before, we think preprocessor seams are especially useful for debugging purposes like tracing function calls. An example of this is shown next where we trace calls to C's malloc function with the help of Mockator:

// malloc.h
#ifndef MALLOC_H_
#define MALLOC_H_
void* my_malloc(size_t size, const char* fileName, int lineNumber);
#define malloc(size) my_malloc((size), __FILE__ , __LINE__)
#endif

// malloc.cpp
#include "malloc.h" 
#undef malloc
void* my_malloc(size_t size, const char* fileName, int lineNumber) {
  // remember allocation in statistics
  return malloc(size);
}

The enabling point for this seam are the options of our compiler to choose between the real and our tracing implementation. We use the option -include of the GNU compiler here to include the header file malloc.h into every translation unit. With #undef we are still able to call the original implementation of malloc.

Screencast