-
Notifications
You must be signed in to change notification settings - Fork 36
Open
Description
Token pasting in the preprocessor is sufficient to introduce a switch/case-like construct; this can act as a vector for variation to propagate through the codebase. This example switches on whether LONG_MAX is 2^31-1, 2^63-1, or undefined:
#include <assert.h>
#include <limits.h>
#include <stdio.h>
#define SELECT(cases, selector) _SELECT(cases, selector)
#define _SELECT(cases, selector) cases ## _ ## selector
// switch(val)
// case 0x7fffffffL: return 4;
#define EVIL_0x7fffffffL 4
// case 0x7fffffffffffffffL: return 8;
#define EVIL_0x7fffffffffffffffL 8
// default: return 0;
#define EVIL_LONG_MAX 0
// }
#define LONG_BYTES SELECT(EVIL, LONG_MAX)
int main() {
assert(LONG_BYTES > 0);
printf("A long is %d bytes\n", LONG_BYTES);
}I originally came up with it as an example case of how the preprocessor is hostile to "partial evaluation", as https://github.com/tendra/tendra attempts to perform, as in their approach LONG_MAX would act as undefined in the initial platform-agnostic preprocessing, resulting in an unconditional assert.
Metadata
Metadata
Assignees
Labels
No labels