ThinkPart

Andrey's blog

 

Where is the problem in the following code?

 

#define MYSQLND_INC_GLOBAL_STATISTIC(statistic) \
 { \
     if (MYSQLND_G(collect_statistics) && statistic != STAT_LAST) { \
        mysqlnd_global_stats->values[statistic]++; \
    } \
 }

I usually don't make this mistake, but in this particular case I did. Can you spot it?

Responses (9) to "Where is the problem in the following code?"

  1.  

    Parenthesis are missing, right?

    if ((MYSQLND_G(collect_statistics)) && (statistic != STAT_LAST)) {

    or

    if ((MYSQLND_G(collect_statistics) && statistic) != (STAT_LAST)) {

    Depending on what you actually mean (I expect the latter is how it is interpreted by default with no parenthesis)

  2.  

    The parenthesis are just fine. There are two things I could think of, firstly the lack of boundary checking on the statistic-index and secondly the fact that mysqlnd_global_stats should probably be MYSQLND_G(stats).

  3.  

    I have no idea what the context here is but I'll take a stab similar to the last comment

    if (MYSQLND_G(collect_statistics) && statistic < STAT_LAST)

  4.  

    If you write macros, wherever you use the parameters you have to enclose them in parenthesis, always. This is what happened:

    if (MYSQLND_G(collect_statistics) && persistent? SOME_STAT:OTHER_STAT != STAT_LAST) {

    What happens? If persistent is fals, then the weird side effect happens -> OTHER_STAT != STAT_LAST is now true and we go into the if(). This is not what we want.

  5.  

    For those that want to know why parameters have to be enclosed in parentheses, checkout out what comp.lang.c has to say:
    http://c-faq.com/cpp/safemacros.html

  6.  

    What is the purpose if you using the next-line breaks \ in this code sample ? are you compiling this code inline or something ? Maybe your macro is overly complex? KISS! http://gcc.gnu.org/onlinedocs/cpp/Macros.html

  7.  

    Ever wondered what will happen, if you run this macro like

    MYSQLND_INC_GLOBAL_STATISTIC(some_variable++)

    ?

    Right, it will break. Use a temporary variable in your macro or even better, get rid of it.

  8.  

    I ran into this the other day while working on some code and was baffeled by this && has operator presedence over != apparently smile

  9.  

    @joschi: Well, you have a point, but I use constants for indexing the array, so it is safe as it is now and doesn't consume stack space.

    @compubomb: yes, I am compiling this code inline, the sole purpose of multiline macros.

    Andrey

Leave a reply

Comments are disabled for this post.