Is it good to use a comma?

I recently (actually only on SO) started up using the C / C ++ comma operator. From what I can say, it creates a sequence point on the line between the left and right side operators, so that you have a predictable (specific) order of evaluation.

I'm a little confused as to why this will be provided in the language, as it looks like a patch that can be applied to code that should not work in the first place. It’s hard for me to imagine what kind of place he could use, which was not too complicated (and needed refactoring).

Can someone explain the purpose of this language function and where it can be used in real code (within reason), if ever?

+8
c ++ c operators
source share
10 answers

This can be useful provided while() loops:

 while (update_thing(&foo), foo != 0) { /* ... */ } 

This avoids duplicating the line update_thing() while maintaining the exit condition within the control expression while() , where you expect to find it. He also plays well with continue; .

It is also useful when writing complex macros that evaluate value.

+11
source share

The comma operator simply separates the expressions, so you can do several things instead of one where only one expression is required. This allows you to do something like

  (x) (y) for (int i = 0, j = 0; ...; ++i, ++j) 

Note that x not a comma operator, but y is.

You really don't need to think about it. He has several more secret uses, but I do not believe that they are ever absolutely necessary, so they are just curiosities.

+8
source share

Everyone says that it is often used in a for loop, and that’s true. However, I find it more useful in expressing the condition of the for loop. For example:

 for (int x; x=get_x(), x!=sentinel; ) { // use x } 

Rewriting this without a comma operator will require at least one of several things that I don’t really like, such as declaring x outside the scope, or the special wrapper of the first get_x() call.

I also plan how I can use it with the C ++ 11 constexpr functions, since I assume that they can only consist of separate statements.

+2
source share

I think the only common example is the for loop:

 for (int i = 0, j = 3; i < 10 ; ++i, ++j) 

As mentioned in c-faq :

From time to time, you find yourself in a situation where C expects a single expression, but you have two things that you want to say. Most of the common (and actually the only common) example is in a for loop, in particular, the first and third control expressions.

+1
source share

The only reasonable use I can think of is for construct

 for (int count=0, bit=1; count<10; count=count+1, bit=bit<<1) { ... } 

since it allows you to simultaneously increase several variables while maintaining the structure of the for construct (easy to read and understand for the trained eye).

In other cases, I agree that this is a bad hack ...

+1
source share

In for loop constructs this may make sense. Although I usually find them harder to read in this case.

It is also very convenient to impose on your colleagues and people on SO.

 bool guess() { return true, false; } 
+1
source share

The comma operator is useful for placing sequences in places where you cannot insert a block of code. As indicated, this is convenient when writing compact and readable loops. It is also useful in macro definitions. The following macro increases the number of warnings, and if a logical variable is set, a warning will also be displayed.

 #define WARN if (++nwarnings, show_warnings) std::cerr 

So you can write (example 1):

 if (warning_condition) WARN << "some warning message.\n"; 

The comma operator is effectively a bad lambda function.

+1
source share

I also use the comma operator to glue related operations:

 void superclass::insert(item i) { add(i), numInQ++, numLeft--; } 
0
source share

When playing Devil's Advocate, it may be prudent to cancel the question:

Is it always good to use a terminator with a comma?

Some moments:

  • Replacing most half-columns with commas will immediately simplify the structure of most C and C ++ code and eliminate some common errors.
  • It depends more on functional programming, rather than imperative.
  • Javascript's automatic semicolon is one of its controversial syntax features.

Whether this practice will increase the “common mistakes” is unknown, because no one does it.

But, of course, if you do this, you will probably annoy your fellow programmers and become a pariah on SO.

Edit: See AndreyT's excellent answer for 2009 Using C-comma . And Joel 2008 also talks a bit about two parallel syntax categories in C # / C / C ++.

As a simple example, the structure while (foo) a, b, c; understandable, but while (foo) a; b; c; while (foo) a; b; c; misleading in the absence of indentation or curly braces or both.

Change # 2 . As AndreyT says:

[Language] C (like C ++) has historically been a combination of two completely different programming styles, which can be called "statement programming" and "expression programming".

But his claim that “in practice, the statement creates a lot more readable code” [emphasis added] is clearly false. Using his example, in your opinion, which of the following two lines is more readable?

 a = rand(), ++a, b = rand(), c = a + b / 2, d = a < c - 5 ? a : b; a = rand(); ++a; b = rand(); c = a + b / 2; if (a < c - 5) d = a; else d = b; 

Answer : they are both unreadable. This is empty space that gives readability - cheers for Python !. The first is shorter. But in the double-colon version, there are more pixels of black space or green space, if you have a Hazeltine terminal - what could be the real problem here?

0
source share

Although it was published a few months after C ++ 11 was ratified, I don't see any answers here regarding constexpr functions. This answer to an unrelated question refers to the discussion about the comma and its usefulness in constant expressions, where the new constexpr keyword was specifically mentioned.

While C ++ 14 constexpr some restrictions on constexpr functions, it’s still useful to note that the comma operator can provide you with predictable operations in the constexpr function, for example (from the above discussion)

 template<typename T> constexpr T my_array<T>::at(size_type n) { return (n < size() || throw "n too large"), (*this)[n]; } 

Or even something like:

 constexpr MyConstexprObject& operator+=(int value) { return (m_value += value), *this; } 

How useful this is depends on the implementation, but these are just two quick examples of how the comma operator can be applied to the constexpr function.

0
source share

All Articles