Another C++ nasty feature

Author: Wojciech Muła
Added on:2015-11-22

I'm fond of C++ weirdness, really. This language is full of traps, and it shocks me once in a while.

Let's look at this piece of code, a part of a larger module:

void validate_date() {

    // ...

    boost::optional<unsigned> clock_hour;
    boost::optional<unsigned> am_pm_clock;

    // ... fill these fields

    if (some sanity check failed) {

        report_error("user has entered wrong time: %d %s",
            *clock_hour
            *am_pm_clock ? "AM" : "PM");
    }
}

We would expect that in case of an error following line will be reported: "user has entered wrong time: 123 PM". Obvious. But please look closer at the code, do you see any mistake? There is one... dirty... hard to notice. I'll give you a minute.

So, the mistake is lack of comma between expressions *clock_hour and *am_pm_clock. However, the code is valid! It compiles! And it took me a little longer than a minute to understand what happened. Explanation is:

We can rewrite the whole expression, now it should be clear:

((*clock_hour) * unsigned(am_pm_clock)) ? "AM" : "PM"

In result method is called with a single parameter of type const char*.

It's bizarre, it's terrible. A language should help a programmer. In my opinion implicit conversions is the worst feature of C++.