1

This is the code:

std::string Query_Set::get_sql() const throw()
{
    std::stringstream out;
    int counter = 0;

    out << "WHERE " << time_name << " >= :start_time_" << counter++ << " AND " << time_name << " <= :finish_time_" << counter++ " AND something_else = :" << counter++;

    return out.str();
}

This code is pretty straight forward, but when I print out this String it does something weird:

"WHERE time >= :start_time_2 AND time <= :finish_time_1 AND something_else = :0"

Have I missed something simple? Why is the counter going backwards?

Samuel O'Malley
  • 3,471
  • 1
  • 23
  • 41
  • Because you are towing with undefined behaviour. You are just invoking a much more complicated version of `i = ++i + i++;`. – Xarn Aug 19 '14 at 08:46
  • Because if you put strings in a stream using the operator `<<` this is parsed starting from the rightmost one. – a_guest Aug 19 '14 at 08:46
  • try to write it in a different format and you'll find out: out << ("WHERE " << (time_name << (" >= :start_time_" << (counter++ << (" AND " << (time_name << (" <= :finish_time_" << (counter++ " << (AND something_else = :" << (counter++)))))))))); – glezmen Aug 19 '14 at 08:47
  • 1
    @a-guest Wrong. It is `((out << stuff) << more) << stuff`. – jotik Aug 19 '14 at 08:48
  • 3
    @quantdev: Yes, it is an issue with sequence points, and the behavior is undefined. A simplified expression is this: `cout.operator<<(i++).operator<<(i++);` -- While the first call to `operator<<` is definitely sequenced before the second call to `operator<<`, the evaluation of the arguments to each of those calls (the i++, in both cases) are unsequenced relative to each other, resulting in UB. – Benjamin Lindley Aug 19 '14 at 09:15
  • Thanks everyone, it confused the heck out of me when I saw the output. – Samuel O'Malley Aug 19 '14 at 11:20

1 Answers1

0

The order of evaluation of arguments to an expression is undefined in C++. The second counter++ may happen before the first. I've even seen different behaviour for such expressions in Clang and GCC.

jotik
  • 17,044
  • 13
  • 58
  • 123
  • 3
    The order is *unspecified* and if thedifferent arguments include writes to the same variable then it is *undefined behaviour*. – M.M Aug 19 '14 at 09:41