Live data from Hacker News

The Subtle Dangers of the Comma Operator (C++)

humanreadablemag.com

31–40 of 49 posts

Re: The Subtle Dangers of the Comma Operator (C++)

#31

Earlier quoted context omitted.

What would you expect that to do instead? C++ doesn't have multiple assignment.

C++17 is capable of multiple variable declaration, which is a similar concept. #include #include std::tuple divide(int dividend, int divisor) { return {dividend / divisor, dividend % divisor}; } int main() { using namespace std; auto [quotient, remainder] = divide(14, 3); cout

Yes, the code

    auto [quotient, remainder] = divide(14, 3);
is not an assignment. In an assignment, you should write something like

    std::tie(quotient, remainder) = divide(14, 3);
which is a tuple assignment written as a single assignment.

This shows the kind of (imho) "ugly hacks" the C++ committee had to make to cover up the historical mistake with the comma operator.

Re: The Subtle Dangers of the Comma Operator (C++)

#32
post #21

Earlier quoted context omitted.

Such misleading code should trigger an error.

Not really an error, since it is syntactically valid C++. It could definitely trigger a compiler warning, though.

Code that violates C++ static typing rules can be syntactically valid too, yet noone is proposing it should be only a warning.

(I find this the most weird thing about C/C++ culture: they are so proud it is static typed, yet oblivious to all the other problems and traps/memory unsafety/undefined behavior/etc.)

Re: The Subtle Dangers of the Comma Operator (C++)

#34
post #27
post #23

I would rather call this "the subtle dangers of function overloading". One thing I like about the C (not ++) language is that it's always clear what function that is being called by looking at the function name. In C++ you have to guess a lot of times (or look very carefully).

Nah. The problem is that , doesn't look like a function, isn't treated as a function by most of your tooling, and so it's very surprising if it behaves like one (plus it's not at all clear what you'd expect a function called , to do in most cases). Polymorphic functions are fine when they have sensible names and are understood as functions by the reader and tooling (of course it helps if your language is actually par…

I don't think the main problem in this article is that "," doesn't look like a function because we are told that it is overloaded so we know it's a function.

The problem is that the behavior of the code silently changes when a function is moved and this is because of the overloading feature in C++. You can get those types of problems in other cases too when you overload functions that have a good name, but maybe it's less likely since I guess the comma operator is already defined for all different types but named functions have to be defined by the programmer.

Re: The Subtle Dangers of the Comma Operator (C++)

#35
post #2

The example (v += 1,2,3,4,5) is neither "nice" nor "expressive". It's confusing and dumb. The reader of this code can't be expected to know what it does. And, looking at the implementation, there's not even an efficiency benefit from doing this. You'd have a more efficient and literate program with std::iota. The rest of the article isn't wrong, but it fails to establish why anyone thinks this pattern is "nice".

It might be a bit extreme but the more I'm exposed to operator overloading the more I think that it's a bad idea 99% of the time.

The only use that seems absolutely in my opinion is when the overload is absolutely transparent mathematically, for instance to implement geometrical transformations on a Matrix class.

That works because in this case you don't actually end up with "custom" behavior, you just expand the standard and well understood notation of the language by plugging the standard and well understood mathematical notation for matrix operations. Anybody who understands this mathematical notation will be able to understand what the code does without additional context.

Anything beyond that is just asking for trouble IMO. It's basically code obfuscation.

Of course C++ has precedent for that sort of insanity, especially with the IMO absolutely bonkers use of the bit shift operators for... input/output processing. A notation that you'll note hasn't had a lot of success outside of C++.

Re: The Subtle Dangers of the Comma Operator (C++)

#36
post #6
post #2

The example (v += 1,2,3,4,5) is neither "nice" nor "expressive". It's confusing and dumb. The reader of this code can't be expected to know what it does. And, looking at the implementation, there's not even an efficiency benefit from doing this. You'd have a more efficient and literate program with std::iota. The rest of the article isn't wrong, but it fails to establish why anyone thinks this pattern is "nice".

In some countries (such as Germany), a comma is the official decimal separator -- so v += 1,5 will look quite innocent...

Only if you forget whether you're reading German or C++.

Re: The Subtle Dangers of the Comma Operator (C++)

#37
post #35
post #2

The example (v += 1,2,3,4,5) is neither "nice" nor "expressive". It's confusing and dumb. The reader of this code can't be expected to know what it does. And, looking at the implementation, there's not even an efficiency benefit from doing this. You'd have a more efficient and literate program with std::iota. The rest of the article isn't wrong, but it fails to establish why anyone thinks this pattern is "nice".

It might be a bit extreme but the more I'm exposed to operator overloading the more I think that it's a bad idea 99% of the time. The only use that seems absolutely in my opinion is when the overload is absolutely transparent mathematically, for instance to implement geometrical transformations on a Matrix class. That works because in this case you don't actually end up with "custom" behavior, you just expand the sta…

I would add string + and += operators to list but that is it really.

Re: The Subtle Dangers of the Comma Operator (C++)

#38
post #34
post #27

Earlier quoted context omitted.

Nah. The problem is that , doesn't look like a function, isn't treated as a function by most of your tooling, and so it's very surprising if it behaves like one (plus it's not at all clear what you'd expect a function called , to do in most cases). Polymorphic functions are fine when they have sensible names and are understood as functions by the reader and tooling (of course it helps if your language is actually par…

I don't think the main problem in this article is that "," doesn't look like a function because we are told that it is overloaded so we know it's a function. The problem is that the behavior of the code silently changes when a function is moved and this is because of the overloading feature in C++. You can get those types of problems in other cases too when you overload functions that have a good name, but maybe it's…

> I don't think the main problem in this article is that "," doesn't look like a function because we are told that it is overloaded so we know it's a function.

Well it's a function in one of the code snippets and not in the other. That it can be both is definitely part of the problem.

> You can get those types of problems in other cases too when you overload functions that have a good name, but maybe it's less likely since I guess the comma operator is already defined for all different types but named functions have to be defined by the programmer.

The problem is that it's not just overloaded but overridden. Subtyping is problematic at the best of times, but the subtyping relationship of C++ lvalues and rvalues is particularly insidious since it is completely invisible in the code.

Re: The Subtle Dangers of the Comma Operator (C++)

#39
The built-in comma operator has strict sequencing semantics:

Every value computation and side effect of the first (left) argument of the built-in comma operator , is sequenced before every value computation and side effect of the second (right) argument. [1]

The same sequencing guarantee is not applied to a user-defined comma operator.

For the similar reasons it's not a great idea to overload && and || either.

[1] https://en.cppreference.com/w/cpp/language/eval_order (point 9)

Re: The Subtle Dangers of the Comma Operator (C++)

#40
post #14

Earlier quoted context omitted.

An even more concise form is built in, and I think more obvious to readers: v.insert(v.end(), { 1, 2, 3, 4, 5 });

I was actually not describing adding elements to a container, but adding up values.

See? That's the problem with arithmetic on containers. Python has that already:

    v += 4, 5, 6
Comma doesn't do weird shit: that's just a tuple of numbers. But "+=" then does weird shit: it means concatenation when v is a standard library list, and element-wise addition when v is a numpy vector.
Post reply on HN