- 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
WTF! He is catching RuntimeException! That logger better be prepared to handle the death of the thread it is being executed on.
Even more disturbing... Why TF did the developer decided he nees to catch RuntimeException? It wasn't because of a compiler warning, that is for sure.
Admin
All it did was log the exception. There's no way for the user to figure out which string was the problem or even how long it got. And then, it would continue running, so you'd have some silently corrupt data passed back, and no idea which entry in the log file corresponded to it.
This would actually make debugging many times harder.
Shortened to the point of saying the opposite of what it did.
Admin
I'll admit my C++ is a little rusty, but I am pretty sure that function is a memory leak. Even if it's C# (where garbage collection would hopefully clean this up before too long), does it really need to instantiate a new StringBuffer on every function call?
Admin
Not only does using a StringBuffer yourself result in needless wordiness, it also generates more bytecode. If you use String concatenation over a StringBuilder, it'll be simpler:
I realize the code isn't the same in both examples, I took the original method and changed it to what I would probably write (if I wrote something like that).
As for returning an empty String if a RuntimeException occurs: If a RuntimeException occurs when you're prepending and appending quotation marks to a String, you probably shouldn't continue as if nothing is wrong. Letting that RuntimeException bubble up to someplace you can actually do something about it, like displaying "Fatal error, program can not continue" to the user would be better. This assumes you can even do that. Once a RuntimeException has occurred, it's unlikely you will be successful trying to build a message and dialog box to display to the user.
Admin
Your C++ is so rusty you don't even recognize that it is Java, not C++ or C#.
Regardless, even
instantiates a new StringBuilder on every method call, so you aren't gaining or losing anything doing it yourself (although as I showed in an earlier comment, letting the compiler do is a lot easier on you).Admin
80% of the time.
Admin
What? Really, what?
You think the best place to deal with your program running out of memory is in a method that prepends and appends a quotation mark to a String? Really?
Really? You really think that's the best place to deal with your program running out of memory?
Wow. Just... wow.
You should read http://java.sun.com/docs/books/tutorial/essential/exceptions/catchOrDeclare.html:
The third kind of exception is the runtime exception. These are exceptional conditions that are internal to the application, and that the application usually cannot anticipate or recover from.
Also good reading http://c2.com/cgi/wiki?DontCatchRuntimeExceptions
Verdict: Your comment is the real WTF.
Admin
Admin
Yup, the equivalent to your concatenation example would be:
This produces the same bytecode, but as you say it's not idiomatic Java code.
Admin
Oh man, you must be so popular with the girls. Yes, the smallest atom of text that you add to a string is the best place to figure out, while debugging a data dump, if and where you have a problem. Your two other options are at the character level (useless) or at the memroy allocation level where you are so far off the call stack that you have to back-track to find exactly what was going on. Place a breakpoint on the log command there and you have an OK, not great, not bad, way of figuring this out. Looks to me like debug code growing up to be something else. You don't like my answer ? Try building real-world systems then.
Verdict: Your ignorance of practice and pragmatics is the real WTF.
Admin
I am going to go get more coffee...
Admin
By "InsertComma", I assume the developer meant "InsertInvertedCommas" (i.e. quotation marks), but used "InsertComma" for brevity.
Admin
2^32 -2
The -2 is you and me, but I'm starting to wonder about you.
(fifth post attempt)
Admin
72% of all statistics are just made up on the spot.
Admin
Really? You think? http://thedailywtf.com/Comments/Insert-Comma.aspx#294939
Admin
Yeah it would be simpler but using a StringBuilder would opt for better performance. Concatenation via "+" is literally translated into a StringBuilder at runtime.
Admin
[quote user="Ben"][quote user="Procedural"] [quote]2. It was probably a shortened method name[/quote]
Shortened to the point of saying the opposite of what it did.[/quote]
Who said the original developer (and not some intern or junior) shortened it ? If we look at the name of the method and try to figure out the code it taints our perception. Of course in theory all method and variable names are great, code is self-documenting, reference manuals are written and code is shipped on time without management pressuring people for one more feature the night before a release. In real life though, with many people looking at and tweaking code, it is best in moments of doubt to try to infer the meaning before trashing the whole code. Other people are smart too. In this case, put a breakpoint on the logger, and I can see a few good uses for that.
Admin
I think a couple of things are making the byte code in the more verbose version longer:
Instead of using a constant '"', you're actually assigning that constant to a variable, then passing the value of that variable into the append() method. The operator+ version uses a constant instead, which eliminates the need to store and load a variable during initialization and use.
Another difference seems to be assigning the StringBuilder to a variable. Again, extra loads and stores because of that. The operator+ version seems to just use the reference at the top of the stack. Which seems silly, I mean you'd figure the java compiler could have optimized out the store, since the variable isn't used outside of the method.
Then again, the invoke virtuals seems equally silly for the same reason. In C++, StringBuilder would be a stack variable, making calls to its methods non-virtual.
I wonder (can't try it right now), doing something like:
return new StringBuilder().append('"').append(s).append('"');
would give bytecode similar to the operator+'s code?
Admin
I assume you're pulling our legs. The stack trace when you run out of memory would get you to exactly the same method as the catch() block. As to why you've run out of memory, it's unlikely to be in this method - and without using a profiler you're unlikely to know.
Admin
True about java's stack dump, I don't use java though. It never seems to fit well in the solutions we look for when we look for either speed of execution, speed of iterative development or availability of labour in this area. Beyond the syntax and pecularities of Java though (which you can harp on, but it won't change the core point), the pattern is clear.
As for memory, it is exactly likely to crash there. A quick glance at the suggested use of the code suggests that the stability of the app depends on the whole return value (here, a CSV output of a table) to fit into useable memory. If your query is too large, nothing here will protect you. You will run out of memory. A better solution is to write the results to a constrained file buffer that is flushed at regular intervals (ex, integer multiples of the block size of the storage device) and one last time at the end, rather than build it up in one heap or stack variable. Then at least you have more leeway before you need to build code defenses against queries that return too large a data set.
Again, this looks to me like evolving code, nothing final. I think we'd all look terrible if our transient, hackish, not-meant-for-prod code was shown here. There's some value in it, and better WTF articles have been posted. Slow day I guess.
Admin
Jamming my thumb up my arse while I wait for code to compile will have little performance impact on my executable, but I'm confident that my coworkers would consider such an act a significant WTF.
If you don't know what you are trying to catch, then WTF are you trying to catch it? I'm quite sure that if this little section has this kind of cruft in it, then I probably don't want to maintain the rest of the code. In fact, based on this code, I'm just sure that somewhere in that inherited project you will find something beautiful like this:
where username, password, and bankacctid are just holders for (unsanitized) request params.
captcha: nulla - a flavorless wafer
Admin
As for question 3, maybe the author fondly remembers his typography lessons and uses "commas" instead of "quotes":
http://en.wikipedia.org/wiki/Quotation_mark
Admin
If by "runtime" you mean "the time when the compiler runs"...
Admin
As with all truly serious problems, Java signals out-of-memory with an Error subclass, not a RuntimeException subclass. That code can't fail in the way you describe. Nor can it fail and hit that exception at all since the delimiter handling won't fail and even a null String won't cause an exception. It's a useless cargo-cultism, a piece of voodoo exception handling that has been waved around some perfectly innocent code in an effort to make the author of it feel a bit better, all to no effect.
Of course, the most serious WTFs are the things it doesn't do, of which failing to deal with embedded delimiters is the most serious (because it makes the code wrong). I'd suggest telling the culprit about little Bobby Tables, but I really doubt they'd learn the right lesson…
Admin
Then why catch a RuntimeException when you want to catch an Error (which would not be caught by this block anyway)?
If someone can tell me any instance in which this block would throw a RuntimeException, I'd love to learn about it.
Admin
What would really look awful is if we claimed that code actually works / makes sense/ is good when it plainly doesn't and isn't.
Admin
The StringBuffer use indicates this predates jre1.5, and the compiler optimization that came with it. Using a StringBuffer was the preferred, recommended solution over direct String concatenation.
See http://java.sun.com/developer/JDCTechTips/2002/tt0305.html
Or the first edition of "Effective Java" or really anything that is older than 1.5 which all pretty much agree on this topic.
Of course, the code then goes on to use string concatenation anyways, and the method name is still silly.
Admin
You (and others here) bore me. Please please if you have no idea about java exceptions don't even try to sound smart.
ThreadDeath (and OutOfMemoryError) are both Errors not Exceptions, they inherit directly from Throwable and not from Exception (like RuntimException does)
I don't see any way for a RuntimeException to be thrown in that piece of code (atleast not when run with a correct/java compatible classpath) - safe from runtime bytecode manipulation that is. StringBuffer and Builder gracefully handle null inputs when appending.
Admin
Indeed, if StringBuffer starts throwing runtime exceptions you have bigger worries than correct String escaping.
Admin
Really? I've always thought the use of exclamation marks adds excitement.
Admin
Yes, the Java zombies now have their moment of glory tripping people up on minutia and arcana (something Java isn't known for at all). Enjoy it. See you in a few years for your next opportunity.
Admin
I assume the try-catch is from earlier code times when there was no StringBuffer/Stringbuilder and the code was just [code]str = '"' + str + '"';[code]
If I remember correct that could throw a Nullpointer Exception if str was null - in times of Java 1.2
Admin
Nice trolling. Go back to whatever hole you crawled out of.
Admin
Disagreement isn't trolling (unless you live in a totalitarian state of something). If you wish to see an example of trolling, pick up any samples of your own writing.
Admin
I think this is quite a non wtfy wtf.
Say this would have been coded in C or something where you dont have such an incredibly clever compiler. Then you might just want to create a function for this purpose (that calls sprintf or something). A wtf that is a wtf only because of a clever language is not a very good wtf.
Where are those really fucked up examples i miss so much?!
Admin
Admin
Not if it is C# - I'm not convinced this is Java, and if it's C# then string concatenation results in some wonky stuff behind the scenes... it is still crap though.
Admin
If you're looking for both speed of execution and development speed java and comparable languages are actually a nice middle ground.
Which is why just truncating a string is a silly idea. What's the point of an export that may or may not contain all the data requested?
And you didn't want to use java because of development speed?
It's just that it's difficult to believe that you'd consider handling out-of-memory errors in some random function by ignoring (but logging) the problem to be a good idea. Either you anticipated that you might not have enough memory and you should have written your code differently, or you didn't anticipate it and you should just log&abort.
Admin
Agreed; as I said above this isn't a language I use so I was unaware of the difference, while taking a cursory look at the code, between an Error and a RuntimeException. I won't defend the code itself as an example for all to see; I just don't think it is so much of a WTF. I could see people using that for a few runs to test a few things, then perhaps forgetting to remove that quick hack or being moved to another project, or teh consultancy being completed, or whatnot. It certainly isn't great code or a perfect example. I would have done things differently in a language that I master. But I've seen much better CodeSODs before.
Admin
Admin
So you use a double quote as an escape character to escape a double quote. What do you do if you want to escape something else?
Admin
Admin
Admin
That's what I love about Java, its nice abstractions remove any need for the user to know about low-level details, unlike that nasty C "strcat()".
Admin
I think that's not the misunderstanding. I think the original coder wanted to call the method "insertAStringWhichMightHaveCommasInItIntoTheCSVFile"
but felt that was too wordy so just called it insertComma.
Admin
What happens when you change methodA to inline?
I.e.
A lot of the extra bytecode is where it's getting the value of sb for each call, even though it's returned by each append method.
Although it can be harder to read, method chaining can reduce the bytecode size
Admin
This: berry@ubuntu:~% cat Foo.java public class Foo { public static void main( String[] args ) { System.out.println( methodA( "foo" ) ); System.out.println( methodB( "foo" ) ); }
} berry@ubuntu:~% javac Foo.java berry@ubuntu:~% javap -c Foo > foo-byte-code.txt berry@ubuntu:~% cat foo-byte-code.txt Compiled from "Foo.java" public class Foo extends java.lang.Object{ public Foo(); Code: 0: aload_0 1: invokespecial #1; //Method java/lang/Object."<init>":()V 4: return
public static void main(java.lang.String[]); Code: 0: getstatic #2; //Field java/lang/System.out:Ljava/io/PrintStream; 3: ldc #3; //String foo 5: invokestatic #4; //Method methodA:(Ljava/lang/String;)Ljava/lang/String; 8: invokevirtual #5; //Method java/io/PrintStream.println:(Ljava/lang/String;)V 11: getstatic #2; //Field java/lang/System.out:Ljava/io/PrintStream; 14: ldc #3; //String foo 16: invokestatic #6; //Method methodB:(Ljava/lang/String;)Ljava/lang/String; 19: invokevirtual #5; //Method java/io/PrintStream.println:(Ljava/lang/String;)V 22: return
public static java.lang.String methodA(java.lang.String); Code: 0: new #7; //class java/lang/StringBuilder 3: dup 4: invokespecial #8; //Method java/lang/StringBuilder."<init>":()V 7: bipush 34 9: invokevirtual #9; //Method java/lang/StringBuilder.append:(C)Ljava/lang/StringBuilder; 12: aload_0 13: invokevirtual #10; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 16: bipush 34 18: invokevirtual #9; //Method java/lang/StringBuilder.append:(C)Ljava/lang/StringBuilder; 21: invokevirtual #11; //Method java/lang/StringBuilder.toString:()Ljava/lang/String; 24: areturn
public static java.lang.String methodB(java.lang.String); Code: 0: new #7; //class java/lang/StringBuilder 3: dup 4: invokespecial #8; //Method java/lang/StringBuilder."<init>":()V 7: bipush 34 9: invokevirtual #9; //Method java/lang/StringBuilder.append:(C)Ljava/lang/StringBuilder; 12: aload_0 13: invokevirtual #10; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 16: bipush 34 18: invokevirtual #9; //Method java/lang/StringBuilder.append:(C)Ljava/lang/StringBuilder; 21: invokevirtual #11; //Method java/lang/StringBuilder.toString:()Ljava/lang/String; 24: areturn
}
Admin
I have relented and added triggering exception handlers as a critically necessary part of the test suite. Not only you need it for code coverage, but -- as you pointed out -- to verify whether you assumptions hold as to an exception being raised in particular circumstances. It seems to me that all code posted on online forums is basically made up in that sense. By "all" I mean more than 99% -- that's "all" enough for me. People just blindly believe whatever they are told, yet checking such things usually requires a few dozen lines of a testcase... If you're a "professional" developer, you should have tools set up to be able to test such things in a couple of minutes.
Admin
Like what? For a carriage return and line return I use the vbcrlf keyword. \n is easier, but I don't use vb.net for succinctness. The original point was how VB programmers were afraid of backslashes. We're not, we just don't need them. Regardless, what does the difference in syntax have to do with the intelligence or ability of the programmer.
Admin
I can't find a language specification handy for VB6 or earlier, no not sure there.
It would be nice to have a clean way to deal with the line-terminator characters, and doubling-double-quotes seems a bit hack-y (but that's how it evolved), but otherwise I find myself agreeing with "VB Programmer". For-why do people seem to think VB(.NET) "vitally needs" backslashes for strings?