Question

i want check sth in if multiple time, i use #define for this ad i want to use it but it doesn't work

#define CHECK_CONDITION(QString condition, start, curr) if(condition == "" ) return true; return (table.commonIn() == "team_id"? list()[start]->team() ==list()[curr]->team() :list()[start]->team() ==list()[curr]->team())

and i use it like this :

if(CHECK_CONDITION(table.commonIn().toStdString(), start, start-idx);) {
   findFalse = true;
}

how can i use this define in my code/ thank you in advance

Was it helpful?

Solution

You could use this modified macro:

#define CHECK_CONDITION(condition, start, curr) \
    if(condition == "" || (condition == "team_id"? list()[start]->team() ==list()[curr]->team() :list()[start]->team() ==list()[curr]->team())

The mistake you have made in this macro:

  • Specifying QString for the condition

  • Returning since that will not have the logic of "return value of macro", but will actually return in the outter function. That is because it has to go through the preprocessor step.

  • You do not need separate branches within the macro as a simple logical OR ("||") can do it.

  • You used the table common in string getter within the macro even though you already passed the condition variable.

  • I would use the back-slash to make it split into pieces for better readability.

and then you could keep the rest of your code like this:

if(CHECK_CONDITION(table.commonIn(), start, (start-idx))) {
   findFalse = true;
}

The mistakes here you made:

  • You had a needless semicolon within the if condition which is invalid C++ syntax.

  • You could get into troubles in general (not here) with not putting the subtraction into bracket.

  • It would be cleaner if you could make two separate variables for the string and the current integer before the CHECK_CONDITION macro call as demonstrated below.

  • You are passing std::string rather than QString.

But it would be even nicer if you could simply the second part like this:

QString myString = table.commonIn();
int curr = start - idx;

if(CHECK_CONDITION(myString, start, curr)) {
   findFalse = true;
}

Disclaimer: I have been trying to make your macro and its caller working, but in general try to avoid macros when possible.

There are cases where they make sense, but there are alternatives like template (which is not applicable here) or inline functions and methods (not sure if applicable in here). Depending on your use case, you can pick up whichever you prefer, but you can get the point of this answer how to make the macro working for your use case.

OTHER TIPS

Preprocessor has no notions of types, so you when you declare a #define with types, you do not need to specify parameter type:

#define CHECK_CONDITION(condition, start, curr) { if(condition == "" ) return true; return (table.commonIn() == "team_id"? list()[start]->team() ==list()[curr]->team() :list()[start]->team() ==list()[curr]->team())}

Besides, a #define is expanded where you use it (the preprocessor replaces CHECK_CONDITION with that block of code), so your code won't compile because of at least one reason: you will be nesting an if inside an if condition, which is a syntax error.

Use a (maybe inline) function, instead:

inline
bool check_condition(QString condition, int start, int curr) {
    if(condition == "" ) return true;
    return (
        table.commonIn() == "team_id"?
            list()[start]->team() == list()[curr]->team():
            list()[start]->team() == list()[curr]->team()
    )
}

This also makes explicit a possible syntax error here: I don't know what you meant with the last two lines, so I left that untouched...

My 2cents: you should see the preprocessor in C++ as a last resort: you have templates, const variables and inline functions.

The main reason why it was left in C++ (instead of using an include keyword alone or the like) is to keep backwards compatibility with C. Never use the preprocessor, unless any other solution is fairly over-complex.

A #define in C/C++ is a macro definition that is a simple textual replacement. This definition is more like a function and is attempting to assign a type to one of the parameters. This isn't legal syntax and hence the QString portion needs to be removed

Overall though this code is not ideally suited for a macro. The arguments start and curr are both used multiple times in the expansion. This means that if a side effecting expression is passed to the macro it will be executed potentially many times. A function would be much more appropriate here

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top