CSC/ECE 517 Fall 2009/wiki2 1 MP
Metaprogramming
The process of writing code-generating programs is known as Metaprogramming [1]. These programs take in either other programs or themselves as their data and manipulate them or finish the run-time tasks at compile time itself. This provides flexibility to the developers as the new changes could be reflected without recompilation. The time it takes the programmers to write such programs is the same as it would take them to write all the code manually [2]. There are two ways that a metaprogramming works – either through the Application Programming Interfaces (APIs) where the internal structure of the run-time engine is exposed to the code at the programmer’s level or through dynamic execution of programming commands that are represented as expressions. Though it is possible for a single programming language to incorporate both of these approaches, generally they provide better support for one approach than the other [1].
Advantages of Metaprogramming
Many programming languages require lots of statements to be typed to perform the tasks but metaprogramming eliminates much of the typing to produce the output. This reduces errors in the code that could be caused by mistyping [1]. Few of the features that are available in one language might be available only through the metaprograms in other languages. However, the main reason behind using metaprograms is not the design issue of a programming language but easier maintenance [1]. There are various uses of metaprogamming. One of them is for using the data at run-time through pre-generated tables. For instance, say for some application a look-up table needs to be created to hold the computation of logarithmic values for the range of numbers. This task can be accomplished either at run-time or write a program to build the table at compile time or by manually calculating it. Though building the table at run-time seems reasonable, it might delay the start up of the program. In such scenarios it is more efficient to write the program to build the static tables [1]. Other most common usage of metaprogramming is to replace boilerplate code. Some of the programs might contain a set of error handlers or a huge list of variable declarations for every instance of the program. In these circumstances it is handy to use the metaprograms such that the code is converted to its respective programming language code before compilation [1].
Metaprogramming can be done through the macro expansions or code generators.
Macro Languages
Metaprograms provide a set of domain-specific languages which are easier to write and have better maintenance than the target language. These domain-specific languages can be created using macro languages [1]. Metaprogramming involves the usage of the textual macro language that consists of textual macros. Textual macros do not have the knowledge of the programming language but they affect the text of the programming language. The most widely used textual macro systems are C preprocessor and M4 macro processor [1].
C preprocessor
C programming language does not have good code-generation capability hence metaprogramming is done through textual macros. These macros are beneficial in many ways as they avoid the overhead involved in function call and the computations can be accomplished without writing the code statements multiple times [1]. Consider a macro SUM, which adds a, b and stores the sum in a.
#define SUM(a, b, type) { type sum; sum = a + b; a = sum; }
This macro can be called in the function in the following way:
#define SUM(a, b, type) { type sum; sum = a + b; a = sum; } void main() { float a = 10, b = 20; SUM(a, b, float); SUM(a, a, float); printf("Value of a: %d \n", a); } Output: Value of a: 40