Skip to content

Macro evaluation order and application order must be opposite #13

@Kerrigan29a

Description

@Kerrigan29a

The order of application of the macros must be the opposite (I suppose). An example:

#define log(x) puts(x)
#define TOSTR(x) _TOSTR(x)
#define _TOSTR(x)  #x
int main(int argc, char const *argv[])
{
    printf("hi from line %u\n", __LINE__);
    log("hi from line " TOSTR(__LINE__));
    puts("hi from line " TOSTR(__LINE__));
    return 0;
}

If I precompile this code with Clang (also with gcc and cl.exe) I get:

#1 "test_short.c"
#1 "<built-in>" 1
#1 "<built-in>" 3
#170 "<built-in>" 3
#1 "<command line>" 1
#1 "<built-in>" 2
#1 "test_short.c" 2
int main(int argc, char const *argv[])
{
    printf("hi from line %u\n", 11);
    puts("hi from line " "12");
    puts("hi from line " "13");
    return 0;
}

In the puts line, Clan use this order to evaluate the macros:

  1. TOSTR
  2. _TOSTR
  3. #x
    4.__LINE__
    BUT applies the macros in the opposite order:
    1.__LINE__
    2.#x

But if I use lcpp:

../lua/src/lua -e 'lcpp = require("lcpp"); local out = lcpp.compileFile("test_short.c"); print(out);'

I get

int main(int argc, char const *argv[])
{
printf("hi from line %u\n", 10);
puts("hi from line ");
puts("hi from line __LINE__");
return 0;
}

Because the application goes in the same order of the evaluation:

  1. TOSTR
  2. _TOSTR
  3. #x
    So, the stringification is applied before the __LINE__ substitution and then __LINE__ is a string, not an identifier

Sorry for my english and thank you for your work.

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