- Feature Articles
- CodeSOD
- Error'd
- Forums
-
Other Articles
- Random Article
- Other Series
- Alex's Soapbox
- Announcements
- Best of…
- Best of Email
- Best of the Sidebar
- Bring Your Own Code
- Coded Smorgasbord
- Mandatory Fun Day
- Off Topic
- Representative Line
- News Roundup
- Editor's Soapbox
- Software on the Rocks
- Souvenir Potpourri
- Sponsor Post
- Tales from the Interview
- The Daily WTF: Live
- Virtudyne
Admin
do{ frist }while(0)
Admin
That loop was probably a misinterpretation of the requirement "make sure this section of code runs exactly once."
Admin
I drunk wiskey many shots night last and smoke bidis and I have handover massive this am.
Admin
Fixed?
Admin
while(0) is what you get when you get a bash scripter to write a loop
Admin
It all depends on the definition of LOG_E_BREAK. If it's doing a unilateral test on errors, and printing a (low-value) message and doing a break if it's non-zero, it's just nasty. If it's doing anything else, it's time to page Mr. Lovecraft to take over its maintenance.
Admin
Actually, my assumption is that it was originally a straight C program with that buried in the middle of a function somewhere. That is quite common in C as you can't declare a variable on the fly without a new scope being opened. That "int const nMatrices..." is why it was done.
Admin
it's heisenberg's principle error logging: you can record the datetime of the error, or the error detail, but never both. making your response to the question "what went wrong?" of "i'm not sure" even more correct
Admin
Admin
Either that, or this snippet was originally a macro. I'm not sure why this particular non-loop would be the thing to break the camel's back; counting the possibility of a "break;" inside LOG_E_BREAK(), there are now three fairly reasonable explanations for why it might be written that way.
Admin
A wild guess:
Admin
Admin
Nope, there is nothing that stops you from creating a scope wherever you wish in C:
Admin
Another useless use of cat.
Admin
Admin
do { } while(0) is a common idiom. The idea is that if you want to exit early on error, you just do a break and avoid a goto. And also if you want to put multiple statements in a macro.
Admin
That is much less of a problem if that snipet was originaly the main loop of the code. Problem is, there is no interface handling on it, so it can not be a main loop of something.
It can yet be explainned by a long time of evolution, while the snippet lost the interface handling, while the "while" was made harmless easlier, so nobody touched it... But WTF! Nobody thought about cutting just the usefull parts of it, instead of the entire thing?
Admin
Exactly. You need less cat food if you use a pipe.
Admin
Continuous Integration would have fixed the build issues. Good unit tests (including memory leak testing) would have handled the memory leak issues.
And the logging, while not actually logging any useful message, are indeed useful -- I can look at the log file, and see the where the log statement is just before the program/thread died.
Admin
Admin
Admin
Admin
Yes, my colleague uses that construct, I hate him for that. It's completely retarded. If you conceptually need a goto (and an error exception is a good reason for a forward goto), do a goto. The break is a goto, it's not because it wears a mask, that it is not a goto. The worse about it, is that a break is for leaving a loop, but here you don't have a loop, so when you see do/break/while, you must considere 2 possibilities, is it or is it not a loop. My colleague even once used that thing, but made really a loop out of it by using a continue in one hidden case (reallocation of memory).
Admin
And unless he's in the shower, he's a dry Waller.
Admin
Honey, Paul's got eyebrows where most guys don't even have places.
Admin
Admin
Something tells me it wasn't that easy though.
Admin
Clearly, the code author was a victim of Dijkstraism.
Admin
A function call isn't much more than a masked goto label.
Everything is a goto.
Admin
It's a slow day at work...does anyone mind if I start a flame war?
Admin
The custom string class also seemed to use a custom memory handler as malloc was probably found wanting in some respect. The occasional new was never explained.
I'm assuming that got garbled, and the custom string class used a custom memory "handler" (or allocator more accurately) instead of plain old new. And I'd certainly expect at least a few occurrences of new in any large C++ app ...
As for the preprocessor logging and homespun persistence layer, I'm lead to believe that there are decent frameworks for this stuff in C++ land now - there was definitely something written in C that abstracted a lot of the DB stuff away last time I did that kind of thing.
Admin
Fuck you. You're not clever.
Admin
Then you have some learning to do. The problem with goto is not that it's somehow evil, it's that you have to generate a separate label every time, and make sure that you use the correct label in the correct place. You don't want to copy-paste a piece of code and accidentally jump to the end of the wrong group. Break takes care of it for you.
Admin
Sounds like you should get your rage on with this guy:
http://www.diag.com/news/DoWhileFalse.html
Personally, I think it's a fine and useful idiom, no worse than an early return (cue the SESE brigade).
Admin
Admin
There's no need for hyper-correction...
In this particular situation, a goto will actually be clearer and easier to understand than an if statement or loop, and would be more suitable.
I think that's what he was trying to say, and I agree. Use a stupid goto if you'd have to write something even more stupid to get the same functionality.
Admin
Your colleague is doubly daft - not sure about the architecture he was targeting, but whether he was actually doing something that would be more optimal at the instruction level is compiler specific (compiler version and setting specific in fact). A quick test suggests he isn't going to see any win on x86:
Admin
A loop, break, or conditional is implemented with an underlying branch instruction in the object code. That doesn't make it a goto. If you write a lisp interpreter in C, that doesn't mean your lisp is "really" C, and if your C compiler generates ASL, that doesn't mean you're "really" writing C. It's good to know what your object code will look like, but we use compilers precisely because goto is unconstrained and has no semantics, while "if" and "for" and "return" are strictly constrained and have clearly defined semantics. Unless you debug the object code, your loops are not gotos.
Admin
The presence of the loop implies that there is a loop when there isn't. The presence of the goto shows there is a goto when there is.
Admin
I don't think there's anything wrong with an early return - if your functions are too long to keep track of the returns, they're too long, period, and you need to break them up. This "construct", however, is basically an early return with an added level of obfuscation. Just return and be done with it, I say. Not to say there couldn't be cases where it's useful, but I can't think of any.
Admin
That makes sense.
Bot how about extracting the code into a separate method/function that returns early? IMO clearer than both.
Admin
Even better!
Hacking the language should really be a last resort, not an established idiom.
Admin
Ugh. </facepalm>
Early returns are TRWTF (and the devil). When debugging a function with N number of returns, you have to add N number of distinct breakpoints just to debug where a function call exits at; such a waste of time and resources. Come on, which would you rather debug:
Admin
function_call1() || function_call2();
instead of
if (!function_call1()) function_call2();
Admin
To me this looks like someone thought they'd be clever and run the code through gcc -E to speed up compile times or something, and thus expanded a bunch of macros, one of which had some broken "log nothing" behavior in whatever particular combination of compile-time defines were set at the time.
Admin
So you're using a permanent change to the code (which increases the chances for screw-ups, like the screw-up in your code sample) to solve a temporary problem (use with debugger) when you could just change how you use the bugger?
Try setting a break point at the top of the function and stepping through it, once you've detected that there is a problem in that function?
Admin
Nope, just Schroedinger's Cat.
Admin
or you could just put a break point of the closing brace of the function.
returning early is generally preferable to trying to track some variable throughout the life time of the function.
Admin
I wonder if this snippet of mine is going to piss anyone off:
It's got a goto and a conditional with a side-effect!
Never had any problem debugging it, even when there were bugs. Never had any problem reading it.
Admin