tags:

views:

54

answers:

1

I was going over the C++ FAQ Lite online. I was browsing inlines again since I haven't found a use for them and wanted to know how the stopped the circular dependency as showed in this answer. I first tried to do the, "Why inlines are better than defines." example with the following code:

#define unsafe(i) \
    ( (i) >= 0 ? (i) : -(i) )

inline
int safe(int i)
{
    return i >= 0 ? i : -(i);
}

int f();

int main(void)
{
    int x(5);
    int ans;

    ans = unsafe(x++);
    cout << ans << endl;
    ans = unsafe(++x);
    cout << ans << endl;

    ans = safe(x++);
    cout << ans << endl;
    ans = safe(++x);
    cout << ans << endl;

    std::cin.get();
    return 0;
}

EDIT:

Great. Got the typo out of the way. Not that I'm bitter that I don't find such errors or anything.

The output is now 6, 9, 9, 11.

However, even with pre-incrementation, shouldn't the first value result in 7?

If the macro is being called twice, then doesn't it go like this:

unsafe(x) // pre-incrementation doesn't modify the value when called.

unsafe(++x) // for all intents and purposes, the incrementation happens before the second call, so the ++x. This is for the first ans = unsafe(x++) if it's being called twice.

By the time we reach the second ans = unsafe(++x), shouldn't the x have been incremented twice? Once by the double call and once when the first double call was finished?

+3  A: 

Instead of:

#define unsafe(i) \
    ( (i) >= 0 = (i) : -(i) )

I think you want:

#define unsafe(i) \
    ( (i) >= 0 ? (i) : -(i) )

In response to your edit:

After the first call to unsafe(x++), x is 7, even though the ans is 6. This is because you have the statement:

ans = ( (x++) >= 0 ? (x++) : -(x++) )

ans is assigned to the middle x++ after the left-most x++ is evaluated. As a result, ans == 6 but x == 7. The difference with unsafe(++x) is that ans is assigned to ++x, meaning the result is ans == x == 9.

Justin Ardini
For some reason I had to stare at that for 30 seconds until I noticed the difference. I curse you, ternary `?:` operator!
Frerich Raabe
Same, but that makes it all the more infuriating when you notice that you just exposed your typo on SO :P Updated question!
SoulBeaver