Austin
Austin

Reputation: 41

C macro expansion not working but writing that line explicitly worked

//#define newScope(string, scopeType) ({ \
        intrprtr.scope = realloc(intrprtr.scope, intrprtr.scope_layer*sizeof(struct Scope)); \
        strncpy(intrprtr.scope[intrprtr.scope_layer-1].string, (string), 255); \
        intrprtr.scope[intrprtr.scope_layer-1].scopeType = (scopeType); \
        })
            //newScope(string, objScope);    // <-- wanted to use macro but it doesn't work. I don't get it
            intrprtr.scope = realloc(intrprtr.scope, intrprtr.scope_layer*sizeof(struct Scope)); 
            strncpy(intrprtr.scope[intrprtr.scope_layer-1].string, string, 255); 
            intrprtr.scope[intrprtr.scope_layer-1].scopeType = objScope;   // <-- this worked

I wanted the code to be more readable, so I used a macro to wrap us to code. I got the following error if I used the macro.

src/parser.c:114:30: error: no member named 'objScope' in 'struct Scope'
            newScope(string, objScope);    // <-- wanted to use macro but it doesn't work. I don't get it
            ~~~~~~~~~~~~~~~~~^~~~~~~~~
src/parser.c:109:48: note: expanded from macro 'newScope'
        intrprtr.scope[intrprtr.scope_layer-1].scopeType = (scopeType); \
        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ^

I did not get this error if I write the code explicitly. Here is the declaration of intrprtr (in parser.h that I included in parser.c)

typedef struct{
    FILE* file;
    char cur_file_name[255];
    int line_num;
    struct Scope {
        char string[255];
        enum ScopeType { msgScope, objScope, codeBlock, func } scopeType;
    }*scope;
    int scope_layer;
}Intrprtr;
extern Intrprtr intrprtr;

According to my understanding, when I passed objScope to second argument of newScope macro, scopeType should expand to objScope. i.e. intrprtr.scope[intrprtr.scope_layer-1].scopeType = objScope; That no member error doesn't make any sense to me especially when intrprtr.scope[intrprtr.scope_layer-1].scopeType = objScope; actually worked. Can someone explain this for me? Thanks

Upvotes: 0

Views: 40

Answers (1)

Eric Postpischil
Eric Postpischil

Reputation: 222536

In the replacement tokens intrprtr.scope[intrprtr.scope_layer-1].scopeType = (scopeType);, the scopeType token is replaced by the corresponding macro argument, objScope, both times it appears, but you want the first one to be a literal member name scopeType, not to be replaced.

Change the macro parameter name to something that is not otherwise used in the replacement tokens.

Upvotes: 2

Related Questions