While other solutions should probably be used, where they are available, there are still situations where macros are required. Some of them are historical reasons, but there are still reasons.
For example, you specify the whence argument to fseek (i.e., SEEK_SET , SEEK_CUR and `SEEK_END). These (for historical reasons) are indicated as macros in the standard, so the developer must define them as fully compatible macros, some kind of evil programmer could write (and blame the library for the consequences):
#include <stdio.h> #ifndef SEEK_CUR int evil = *(int*)0; #endif
But as far as I see, there is no reason why they could not write:
enum __WHENCE_T { __SEEK_CUR, __SEEK_END, __SEEK_SET }; #define SEEK_CUR __SEEK_CUR #define SEEK_END __SEEK_END #define SEEK_SET __SEEK_SET
Another historical reason is that the compiler could create more efficient code when using macros. The code that was written then may still be around and contain constructs that worked better then (and still work pretty god).
Modern reasons: if you need to use values ββoutside the C compiler. For example, as mentioned, if you want to use a value in assembler code (or in some other language). All you have to do is make sure the header does not expand to something (containing the C code) if it is not compiled with the C compiler. For example:
#define NUMBER 42 #ifdef __STDC__ extern int variable; int function(void); #endif
if it is enabled from assembler, the NUMBER macro will expand (and expand to the same as for C programs).
skyking
source share