开发者

Is this a valid macro in C?

If I use the macro:

#define AND

in the following way:

if(...)
{
...
}
elseANDif(...)
{
...
}

What output does the preprocessor produce?

Edit: I intend to use:

#define TEST(params) if(...){...}else  

the ... in if(...) is a complicated expression using params

the ... in {...} performs some operations & is independent of params

#define AND

TEST(x1) AND TEST(x2)
{
    //the code for the final else
}

Is the AND helping here or can I do with开发者_StackOverflow社区out it?


No, this isn't going to work as you expect. And you can test what the preprocessor does by running your code through cpp.

eliben@eliben-desktop:~/temp$ cat z.c
#define AND

if(...)
{
    ...
}
elseANDif(...)
{
    ...
}

eliben@eliben-desktop:~/temp$ cpp z.c
# 1 "z.c"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "z.c"


if(...)
{
    ...
}
elseANDif(...)
{
    ...
}

The technical reason is that when cpp expands macros it looks for a complete identifier token matching this macro's name. I.e. in your case, it looks for the identifier AND. However when it parses the code it doesn't find such an identifier. It finds elseANDif which is quite a different identifier. It has no way to break elseANDif into constituents, and that's a good thing because otherwise macros would work very badly. Imagine:

const int FUSIONDEBUG = 5;

Whatever that means, in real C code this would break awfully, since NDEBUG is almost always defined in production code to be empty (google on what NDEBUG means).


Regarding your edit, the best advice I can give you on such matters is DON'T DO IT. (ab)Using macros like this may appear at first to make the code more readable, but in the long term it makes it much less readable, with the added peril that macros are tricky to get perfectly right and with certain combination of tokens can blow up on you badly.

So you can definitely do without the AND as well as without the TEST altogether.


This:

#define TEST(condn) if(...){...}else

is nonsense; what do you expect the ellipses (...) to do!?

the example usage you gave would expand to

if(...){...} else if(...){...}else
{
    //the code for the final else
}

which is patently nonsense; where is the condn argument used?. Either way whatever you really intended the AND has no effect other than dummy readability. If you are trying to invent a new language, the C preprocessor is not the way to do this. I can see no advantage to what you appear to be trying to achieve over more straightforward code.

If you intended:

 #define TEST(condn) if(condn){/*some code*/}else

then how is the resultant:

if(a==b){/*some code*/} else if(b==c){/*some code*/}else
{
    //the code for the final else
}

better than:

if(a==b || b==c)
{
    /*some code*/
} 
else
{
    //the code for the final else
}

where /*some code*/ is not unnecessarily duplicated?

Note that here the single condition chained by || is equivalent to your multiple conditions chained by else if, so even if you use the TEST macro, there is no need to use it that way when:

TEST( a==b || b==c)
{
    //the code for the final else
}

will suffice.

Macros are often ill-advised at the best of times, but you have chosen a particularly prime example of macro abuse! Consider for example how you might debug such code in a source-level debugger.


The short answer to your question is "yes". You can certainly do what you are suggesting. Here is a basic, working example:

#include <stdio.h>

#define AND
#define TEST(params) if (!params) { printf(#params " was false\n"); } else 

int main(int argc, char ** argv)
{
    int param_1 = 1;
    int param_2 = 0;

    TEST(param_1) AND TEST(param_2)
    {
        printf("success!\n");
    }
}

After macro expansion, the code would essentially look like this:

int main(int argc, char ** argv)
{
    int param_1 = 1;
    int param_2 = 0;

    if (!param_1) { printf("param_1 was false\n"); } else 
    if (!param_2) { printf("param_2 was false\n"); } else
    {
        printf("success!\n");
    }
}

As pointed out by others, doing something like this is questionable because it messes with the way people read code and can make future debugging difficult. In a case such as this, I would definitely recommend using a function call if at all possible. This is the approach that Secure recommends in his comment:

int test_parameters(int params)
{
    if (!params) { printf("bad parameters"); return 0; }
    else { return 1; }
}

int main(int argc, char ** argv)
{
    int param_1 = 1;
    int param_2 = 0;

    if (test_parameters(param_1) && test_parameters(param_2))
    {
        printf("success!\n");
    }
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜