|
|
#1 |
|
Any thoughts on the comma operator (C/C++/Obj-C?)
I recently decided to insert a few comma operators into the output lines of my C++ code and I feel like they've cleaned up my code a lot.
For example, I had this code: Code:
cout << "Can't place " << v << " at " << x << ", " << y << endl << "Add: "; printBitsForInt(mask); cout << "Old: "; printBitsForInt(conflicts[v-1]); cout << endl; And by introducing a few sequence points I feel like I was able to clean it up quite a bit, improve legibility, and reduce the amount of space it takes up. Code:
cout << "Can't place " << v << " at " << x << ", " << y << endl
<< "Add: ", printBitsForInt(mask), cout << endl;
<< "Old: ", printBitsForInt(conflicts[v-1]), cout << endl;
I'm wondering if I could use the same basic idea in the future with some C or Obj-C code. Also, is there any real difference between using the comma operator and inserting a semicolon? I feel like the compiler probably generates the same code for both, wouldn't it? Are there any other good uses for the comma operator?
__________________
Battery Status - On the Mac App Store
The only app that'll estimate when your wireless devices will need their batteries changed. Like it on Facebook! |
|
|
|
0
|
|
|
#2 | ||
|
Quote:
Quote:
Very, very rare. This would be an example: Code:
while (tmp = x*x + y*y, tmp > 10 && tmp < 20) { ... }
Code:
for (;;) {
tmp = x*x + y*y;
if (tmp <= 10 || tmp >= 20) break;
...
}
|
|||
|
|
0
|
|
|
#3 |
|
I've never felt the need to use it, I've rarely seen it at all, really. Executing multiple statements in the incrementor of a for, etc. is a rare but useful case. I had to fix one very pernicious bug caused by a comma operator, which put it into my bad graces.
As for the difference between ; and , is that ; ends a statement and , joins statements and evaluates to the right operand. x = haveFun(), eatPie(), takeNap(); Will result in x being set to the result of takeNap(). I'm not big on C++, but %b is the format specifier for printing the binary representation of an int. Why not return a std::string from your helper, then just keep using <<. Having the function print after formatting that way limits the utility. -Lee Edit: figured there was a better way. Try: cout << setbase(2) << myInt << endl; Last edited by lee1210; Feb 21, 2013 at 10:58 PM. |
|
|
|
0
|
|
|
#4 | ||
|
Quote:
My thoughts regarding the comma operator: 1. It can make it difficult to set a breakpoint at a statement, if the statement is a bunch of comma-separated expressions. Better to make each one a separate statement. 2. There were times when an aggressive optimizer wouldn't rearrange the parts of a comma'ed statement, but it would rearrange statements with semicolons. I don't know how true that is any more, since optimizers are a lot better these days. Still, it wouldn't surprise me if commas aren't entirely interchangeable with semicolons when it comes to code rearrangement. 3. If you want to add something between the comma'ed expressions, it gets ugly very quickly. Even when the expressions may seem to be inseparable in the design, things can evolve and change over time. 4. One place where I still use commas is in the initializer (1st) or the iterator (3rd) clauses of a for loop, e.g.: Code:
for ( a = x, b = y; someCondition; ++a, --b )
{ something using both a and b; }
EDIT Quote:
Code:
(x = haveFun()), eatPie(), takeNap(); Code:
a = x, b = y I don't have the time right now to write up a test case, but doing so would prove enlightening on several levels. One level is the fundamental operation of comma: its precedence, associativity, debuggability, etc. Another level is the potential confusion or errors when using it, even for skilled programmers with years of experience. I include myself in that bunch of confused error-makers, because I could be wrong. It's exactly the kind of thing I'd only trust after writing test code for, and frankly, if I have to write a test to figure out how it works, is it really worth using in real-world code? I could name all my variables as nothing but different numbers of _'s, too, but why would I do that except to sow confusion? Last edited by chown33; Feb 22, 2013 at 12:35 AM. |
|||
|
|
0
|
|
|
#5 |
|
Oops, there you go.
Code:
x = (haveFun(),eatPie(),takeNap()); One more data point for myself generally avoiding the , operator. Clauses in a for loop are the rare exception. -Lee |
|
|
|
0
|
|
|
#6 | |
|
Quote:
Code:
return f (x); Code:
int result = f (x); return result; Last edited by gnasher729; Feb 22, 2013 at 08:09 AM. |
||
|
|
1
|
|
|
#7 |
|
Yikes. I'm ashamed to admit after years of study and more years of development work on C-esque languages, I'd never even heard of the comma operator.
I'm kind of glad I didn't though. If there's one thing I've learned through experience it's the importance of code maintainability, and having easily readable and debuggable code is far, far more important than keeping code terse. Even reading through the Wikipedia, the simple examples gave me a shiver: i = (a,b); // b i = a,b; // a I can see how one of those lines, buried in hundreds of lines of code, could introduce an easily missed bug.
__________________
Mac <- Macintosh <- McIntosh apples <- John McIntosh <- McIntosh surname <- "Mac an toshach" <- "Son of the Chief" |
|
|
|
0
|
|
|
#8 |
|
Occasionally, I'll come up with an amazing line of code that is pure poetry. I take a sip of tea, then break the line into about 30 separate lines of easily readable code and let the compiler do it's job of making the executable efficient.
Coming back to fix something 4 months and 6 projects later on poetry is a serious PITA.
__________________
TI-99/4A, tape cassette, 12" B&W Zenith |
|
|
|
1
|
|
|
#9 |
|
That's why you turn on all compiler warnings that you can. i = a, b; doesn't even compile on my Mac (it produces a warning because the value b is ignored, and I turn all warnings into errors).
|
|
|
|
0
|
|
|
#10 |
|
This is why I tend not to go for "clever" code. I work on a codebase that's huge (500K+ lines), historical (some of this code was written in the 80's) and maintained by dozens of people. Code I wrote today might be maintained by someone else 6 months from now when I transfer to a different project. Likewise, I'll frequently inherit code written 4 years ago by other programmers who no longer work with the company.
To me, good code is cleanly formatted, straightforward, and easy to follow (with comments where helpful). If I have to stop and say "wait wait wait, what is this doing?" then that slows things down and potentially allows bugs to go unnoticed.
__________________
. |
|
|
|
1
|
|
|
#11 |
|
Huh. Can I have it put a space after every 9th bit/digit?
__________________
Battery Status - On the Mac App Store
The only app that'll estimate when your wireless devices will need their batteries changed. Like it on Facebook! |
|
|
|
0
|
|
|
#12 |
|
You can probably write your own modifier, but otherwise I'd just write a formatter that returns what you want to print. I'll happily admit that I don't know the right way to do this safely as it pertains to memory in C++, but surely this is a solved problem.
-Lee |
|
|
|
0
|
|
|
#13 | |
|
Quote:
__________________
Android sucks.
|
||
|
|
0
|
![]() |
|
«
Previous Thread
|
Next Thread
»
| Thread Tools | Search this Thread |
| Display Modes | |
|
|
All times are GMT -5. The time now is 11:21 PM.








Linear Mode
