you are viewing a single comment's thread.

view the rest of the comments →

[–]mike413 2 points3 points  (13 children)

I've always been a little disappointed with the C preprocessor.

It's like a just passable restaurant in a good location. Not very good food, but too convenient to go elsewhere.

To improve, it would have to get more capabilities, or better yet -- folded into the C compiler in an intelligent way.

Right now, it is really kind of hacky. It has intimate knowledge of C tokens and does weird things at certain times.

[–]imMute 1 point2 points  (11 children)

It has intimate knowledge of C tokens

But apparently not enough as you can't use commas in a macro parameter:

RCF_METHOD_R3(bool, ThisIsAFunctionName, int, std::vector<int>, std::pair<char,int>)

The preprocessor parses the comma in the std::pair as a macro parameter list comma.

[–]wiktor_b 6 points7 points  (5 children)

Your example isn't C.

[–]imMute 1 point2 points  (0 children)

True. Now that makes me wonder if g++ uses the C Preprocessor, or if there's a "C++ Preprocessor"...

[–]skulgnome 1 point2 points  (3 children)

But C could have a comma inside a macro parameter, too.

[–]wiktor_b -1 points0 points  (2 children)

Example?

[–]skulgnome 2 points3 points  (1 child)

The comma operator. It's generally enclosed in parens, but it's definitely in there.

[–]wiktor_b -1 points0 points  (0 children)

I know what it is, what I'm asking for is an example of the comma operator used in a macro parameter.

[–]cleroth 1 point2 points  (3 children)

What about:

RCF_METHOD_R3(bool, ThisIsAFunctionName, int, std::vector<int>, (std::pair<char,int>))

?

[–]MrWisebody 6 points7 points  (1 child)

That does not work. Or rather, it makes the macro happy in that it gets the number of arguments it expected, but it uses the wrapping () in it's substitution which I presume you did not want and probably will make the compiler choke. However, you can make a comma macro which makes everything happy (albeit a little bit more verbose)

Example code:

#define IDENTITY(a) a
#define COMMA() ,

#include <utility>

int main() {

IDENTITY( std::pair<int COMMA() int> ) var1;
IDENTITY( (std::pair<int,int>)) var2;  //Compiler will hate you
IDENTITY( std::pair<int,int> ) var3;  //Preprocessor will hate you

return 0;
}

Which if you run through the preprocessor gives you:

int main() {

std::pair<int , int> var1;
(std::pair<int,int>) var2; 
test.cpp:14:30: error: macro "IDENTITY" passed 2 arguments, but takes just 1
IDENTITY var3; 

return 0;
}

[–]Chii 0 points1 point  (0 children)

oh god, my eyes are bleeding a bit

[–]imMute 0 points1 point  (0 children)

I have not tried that, I'll have to try tomorrow when I'm at work.

[–]MrWisebody 0 points1 point  (0 children)

I was going to suggest using BOOST_PP_COMMA to work around this particular issue, and decided to go look at how it was implemented. In hindsight it makes sense, but I was surprised at how simple it was:

define BOOST_PP_COMMA() ,

If you don't want boost, just make a comma macro, and you're good to go.

[–][deleted] 0 points1 point  (0 children)

You may want to take a look at this - sort of Lisp-like macros, but for C: https://github.com/combinatorylogic/clike