Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Function-like macro expands to nothing

This is a very strange problem. It's a very simple looking function-like macro, and I have seen its examples many times. I have even used it before! However, I just couldn't get this working after 6 hours. I got exhausted, and decided to ask here. Maybe somebody spots the problem. The minimal reproducible case is:

enum e {
    x, y, z,

#define Func(X, Y, Z) \
  my_##X = Y

Func(x, y, z),
};

It's used in clang source code in a similar way. I, too, include a file that's containing both the definition and use of the macro.

EDIT:

Thanks a lot for answers and comments. It's true that I have used Godbolt, but after my build failed. It turned out that macro has never failed during my build. That's because I haven't used the macro! It's not used, so it never generated an output. That's quite shameful. I have to accept my mistake, and move on. I must have checked it by preprocessing locally. Getting empty string in Godbolt made me believe that I am doing something wrong.

like image 934
user1150609 Avatar asked Nov 12 '20 09:11

user1150609


Video Answer


2 Answers

Apparently (as noted by @Shawn in comments) this is because the compiler output in Godbolt "unused labels" (the "funnel" filter icon) is checked and if you run with with pre-processor output -E it will filter out unused things.

You can fix this by simply referring to my_x somewhere in the compiled program or simply uncheck "unused labels" in Godbolt when viewing pre-processor output.

As a side-note, please note that "trailing comma" in the end of enums was added in C99, so if you use an older C90 compiler you might experience strange compiler hiccupts because of that.

like image 171
Lundin Avatar answered Oct 22 '22 21:10

Lundin


As per Godbolt open issue (feature request) 1380, Godbolt does not (yet) support the -E option [emphasis mine]:

Support -E output in some way #1380

[...]

apmorton commented on May 15, 2019

appears to be caused by the combination of label and directive filtering.

[...]

you should probably turn off any filters that are meant to parse assembly when you are instructing the compiler to output something other than assembly.

not sure that this is really a bug in the filters, as they are technically doing what they are supposed to - its just that they are running on output they aren't meant to.

maybe it could detect usage of -E and disable filters meant for assembly output?

partouf commented on May 18, 2019

The assembly parser isn't really meant to support -E, it's expecting asm and not C++, so there's really nothing wrong.

We can consider disabling the parser on -E, but we would need to detect that on a per-compiler basis.

Thus, the issue mentioned by OP as well as the more minimal example shown by @Jabberwocky in a comment both produces the expected program if actually compiled, but not the expected preprocessor output when using the -E option (which should do nothing except preprocessing).

like image 1
dfrib Avatar answered Oct 22 '22 22:10

dfrib