Skip to content

Macro evaluation order and application order must be opposite #13

Open

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.

Activity

  1. umegaya commented on Feb 26, 2015

    @umegaya
    Collaborator

    hmm, I understand the problem, but its not so simple.
    consider following example. it evaluate FUNC prior to __ARG.
    we are now thinking good way to handle both.

    BTW: please do not mind your english. I'm Japanese which has poor english skill :<
    and your english is far more better than mine 👍

    #include <stdio.h>
    #include <stdlib.h>
    #define FUNC__ARG 500
    #define FUNC100 400
    #define __ARG 100
    #define FUNC(x) FUNC##x
    int main(int argc, char *argv[]) {
        printf("%d\n", FUNC(__ARG)); //prints 500, not 400
    }
  2. umegaya commented on Feb 26, 2015

    @umegaya
    Collaborator

    hi, it should be fixed with umegaya/ffiex#20
    I will backport this fix to lcpp after CI passed. thanks.

  3. added a commit that references this issue on Feb 26, 2015
  4. Kerrigan29a commented on Feb 26, 2015

    @Kerrigan29a
    Author

    If I understand you correct, you say it must return 400 and not 500, but in fact the it must print 500 and not 400. Examples:

    In Ubungu with gcc:

    $ echo "#include <stdio.h>
    #include <stdlib.h>
    #define FUNC__ARG 500
    #define FUNC100 400
    #define __ARG 100
    #define FUNC(x) FUNC##x
    int main(int argc, char *argv[]) {
        printf("%d\n", FUNC(__ARG)); //prints 500, not 400
    }" > test.c
    $
    $
    $ gcc -E test.c | tail -n 3
    int main(int argc, char *argv[]) {
        printf(%dn, 500);
    }

    In Mac with Clang:

    $ echo "#include <stdio.h>
    #include <stdlib.h>
    #define FUNC__ARG 500
    #define FUNC100 400
    #define __ARG 100
    #define FUNC(x) FUNC##x
    int main(int argc, char *argv[]) {
        printf("%d\n", FUNC(__ARG)); //prints 500, not 400
    }" > test.c
    $
    $
    $ clang -E test.c | tail -n 3
    int main(int argc, char *argv[]) {
        printf(%dn, 500);
    }

    In Windows with cl.exe

    > notepad test.c
    >
    >
    > cl.exe -E test.c
    [...]
    
    int main(int argc, char *argv[]) {
        printf("%d\n", 500);
    }
  5. umegaya commented on Feb 26, 2015

    @umegaya
    Collaborator

    If I understand you correct, you say it must return 400 and not 500

    oh, that is misunderstanding :<
    what I mean with this sample is,
    "if evaluation order is same as the case of #x (stringify operator),
    this program should print 400 but actually it prints 500, so evaluation order is different for both (# and ##) case"

    and current lcpp is made for processing ## (concat operator) correctly, it causes problem that you report.

  6. umegaya commented on Feb 26, 2015

    @umegaya
    Collaborator

    anyway, it has been fixed with
    https://github.com/umegaya/ffiex/blob/master/ffiex/lcpp.lua (see here)
    I will port the fix to this project in a while (sorry for my laziness)

  7. m-schmoock commented on Feb 26, 2015

    @m-schmoock
    Owner

    "(sorry for my laziness)"
    no problem, im also very lazy :D

  8. added a commit that references this issue on Mar 2, 2015
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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