• P (unregistered)

    TRWTF is not writing a macro to rewrite a > b > c into a > b && b > c. After all, some people have managed to implement sorting using nothing but macros.

  • Simon Clarkstone (unregistered)

    I think the macro should be more like:

    #define MIN(a,b) ((a)>(b)?(b):(a))

    in case a or b have an operator lower-precedence than ">" in them (though that's a much lower risk than the analogous one for a "square" macro). It still doesn't work right with expressions that have side-effects.

    The WTF code also uses "b" as a condition later on in the expression, which is surely wrong too.

  • Stella (unregistered)

    int lowestVal(int a, int b, int c){ return (a<b) > (a<c) ? c : (a<c) > (a<b) ? b : a; }

    Fixed.

  • Zach (unregistered)

    I'm thinking that the person who wrote "a > b > c" is more likely to be a Python programmer than a mathematician. This dubious feature of Python confuses students all the time. It also leads to some weird, inadvertent cases even in Python:

    (False == False) in [False] False False == (False in [False]) False False == False in [False] True

    See https://github.com/cosmologicon/pywat

  • ThndrPnts (unregistered)

    MIN(MIN(a, b), c)

    ...I heard you like macros, so I put macros in your macro

  • Somebody Somewhere (unregistered)

    And we can't forget about the "fun" those macros can cause when you're comparing, say... MIN( 1, someFunctionWithLotsOfSideEffects() );

    "Why are we sometimes getting duplicate entries in our database?" "Who cares, ship it!"

  • K. (unregistered) in reply to Stella

    You can also use the standard library:

    std::min({a, b, c})

  • (nodebb) in reply to K.

    std::min is C++, not C.

  • dpm (unregistered)

    See https://github.com/cosmologicon/pywat

    I will not. I avoid situations in which I need to roll a saving throw versus my sanity.

  • Helten (unregistered) in reply to Stella

    Not fixed. lowestVal(2, 2, 1) returns 2.

  • (nodebb)

    Well.... that code is neither an Elegant tern nor a Common tern

  • Black Mantha (unregistered) in reply to Simon Clarkstone

    I'd also make it inline. With a decent compiler that should be equivalent to a #define without the problems with doubly evaluated parameters.

    inline int lowestVal(int a, int b, int c){ return a > b ? b > c ? c : b : a > c ? c : a; }

  • Stella (unregistered) in reply to Helten

    /* only works for strictly orderable integers */

    Fixed.

  • my name is missing (unregistered)

    Clearly one tern deserves another.

  • gnasher729 (unregistered)

    The implementation of MIN in the standard library I use stores the values into two local variables. As a result, you can calculate MIN (x++, f (y++)) and it will evaluate both expressions once and return the correct value.

  • (nodebb) in reply to P

    Am I missing a joke here? I don't read "a > b > c" as one term in this line. It is probably meant to say a > (b > c ? c : b) ? (b > c ? c : b) : a

  • sizer99 (google) in reply to Simon Clarkstone

    Came here to say that - that's the biggest WTF with macros, usually. You MUST paren every parameter everywhere it appears, because inevitably someone will invoke it with a complicated expression and precedence will make it fail miserably.

    Wrong: #define FOO(x,y) x + y Right: #define FOO(x,y) ((x) + (y))

    But by convention you're on your own for side effects, so don't do it.

  • Little Bobby Tables (unregistered) in reply to sizer99

    The biggest WTF with macros is using the stupid things in the first place. They are the most braindead, retarded, spastic, crippo, thaliddy idea ever made.

  • Wairapeti (unregistered)

    Hard to read macros or a really simple function:

    int lowestVal(int a, int b, int c){ min = a; if(b<min) min = b; if(c<min) min = c; return min; }

  • Simon Clarkstone (unregistered) in reply to Little Bobby Tables

    If you think that's bad: In the build process of the computer game Nethack, one of the source files (the monster definitions) is compiled twice with different sets of macros enabled to produce two of the the main data tables.

  • Chris (unregistered)

    We got caught out a few times here. We had a short-cut for a commonly used method as #DEFINE DoStuffA if (someCondition) DoStuff.

    Works well, unless you put that in the middle of an if-else statement. As in, if (something) DoStuffA() else DoSomethingElse(). The "else" isn't being applied to the condition you thought it was. The fix was to throw curly brackets around the define.

  • Pietro (unregistered)

    So, this is the kind of programmers who code Internet-of-Things software? but more at large, the kind of companies too (no code reviews, no tests)? No wonder there is a dedicated site to IoT called Internet-of-S**t

  • Zayn (unregistered)

    Macros are poor man's inline functions. There is no reason to use them for actions such as described in this WTF.

  • Sandman (unregistered) in reply to ThndrPnts

    That very same expression popped into my head

  • Robert (unregistered)

    Only one bracket missing...who can remember all operator precedences ?

    a > ( b > c ? c : b ) ? b > c ? c : b : a

  • SyntaxError (unregistered)

    Tern down for what?

  • unregistered (unregistered)

    “Multiple exclamation marks,' he went on, shaking his head, 'are a sure sign of a diseased mind.”

    ― Terry Pratchett, Eric

  • Simon Clarkstone (unregistered) in reply to Robert

    Damn, you're right; how did we all not spot that.

  • (nodebb) in reply to Robert

    Thank you! Now that darn thing makes sense.

  • (nodebb) in reply to Zayn

    (And to Little Bobby Tables ):

    Nope. Macros are a great abstraction tool which made programming in Common Lisp extremely more fun.

  • Si (unregistered) in reply to Zach

    Agreed, but I don't find it that weird. Operator precedence is a standard thing (https://docs.python.org/3/reference/expressions.html#operator-precedence), and left-to-right evaluation of operators with the same precedence is also fairly standard; it's just that comparison operators are chained rather than evaluated (https://docs.python.org/3/reference/expressions.html#comparisons). I've never worked with another person who can do Python so I may have ten years of bad self-taught info, but I'd generally expect anybody using arbitrary chaining in committed code to ensure that everybody else working on the project was comfortable enough with it to be able to read and understand it, otherwise they should get their brackets/parentheses out (at the risk of evaluating arguments multiple times).

  • Gnasher729 (unregistered) in reply to Chris

    Solution: do { if (condition) statement; } while (0)

    Can be used anywhere.

  • Tgape (unregistered) in reply to Robin Koch

    What you're missing is that this site is mostly trolls.

    Yeah, that's what was meant, but not what this does. Everyone here but you is laughing at what it does versus what was intended.

    I think this is one of the cases where it's better to just do MIN(a, MIN(b,c)), and if that has unwanted effects due to side effects of a, b, and c, either use a real function or use a real function to wrap MIN(a, MIN(b, c)). That said, I expect even that was a problem, so they exploded out what the macros were doing by hand, not realizing that the problem was the macro lacked any parentheses, so would be wrong in all but the most trivial cases.

  • symbiont (unregistered)

    this is what you get with weak typing

Leave a comment on “Tern Down Service”

Log In or post as a guest

Replying to comment #:

« Return to Article