Skip to content

Token pasting as a vector for variation #44

@eternaleye

Description

@eternaleye

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

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions