• (nodebb)

    Yikes.

  • WTFGuy (unregistered)

    Yikes.

    (Copied and pasted into my comment class for good measure.)

  • anonymous (unregistered)

    Well if the directive says that repeated code had to be replaced with a method then of course every class needs to have that method.

  • Black Mantha (unregistered)

    A beautifull layer cake of wtf'ery. Good intentions, application without understanding and bad execution piled on top of each other that combines in a way that's not actually doing anything wrong. Because it's not doing anything. And because what it was trying to do didn't need doing.

  • Vault_Dweller (unregistered)

    To solve the problem you need to do nothing. This method does nothing. Ergo this method solves the problem.

  • NoLand (unregistered)

    I think, the real problem with this method is that it takes an argument, which introduces unnecessary overhead. — Just set a local variable to Nothing, goal achieved.

  • Steve (unregistered) in reply to Black Mantha

    This actually might make things hang around longer. Now, the GC sees another reference to your object farther along in your code, so it needs to keep the object alive in order to throw it into the release routine. Without that, the GC would have been able to release the object earlier. I can easily imagine a scenario where you have a long (or long running) bit of code with that release called at the end, so your objects hang around just because of that pointless final reference at the end.

  • Edd (unregistered)

    The memory cabal trying to trick you into not setting everything to null as usual.

  • SetCommentToNothing (unregistered) in reply to Steve

    Wow. This is a great WTF, so many layers distilled into such a short snippet.

    @Steve I think the .Net JIT compiler is probably clever enough to first inline and then optimise away the entire waste of space, but yes, it's certainly possible that doing this could actually make GC performance worse.

  • Koro (unregistered) in reply to SetCommentToNothing

    Considering that this is the entire implementation of GC.KeepAlive, I'd say that yes.

  • Gamedev (unregistered)

    '“to improve the performance of the garbage collector,” you know you’re probably in for a bad time'

    This one stood out at me, given I've spent much of the last several months trying to inprove garbage collection performance... because in Game dev every fraction-of-a-millisecond can matter! Sometimes it's less bad time and more par for the course (sadly, I wish we could avoid GC'd languages altogether)

  • (nodebb)

    So a software engineer walks into a bar and orders a DRY martini. Then he orders another. //I'll be here all week. Try the veal

  • Tim (unregistered)

    Surely if you have multiple references to the same object, you could just free them all by calling that function in a loop?

  • (nodebb)

    They should have turned that into an extension method

  • Clbuttic (unregistered)

    I think I injured myself slapping my forehead.

  • Sole Purpose Of Visit (unregistered) in reply to Gamedev

    If that's what you want, it's technically trivial. In C#, you just bridge to C++/CLI and use RAII. Been a while since I used JNI, but as far as I can remember, the same applies. Or you could use Rust, which has a very high level pervasive attitude to object ownership. (Slightly less technically trivial, I will admit.)

    Or, in fact, you could use [B}Visual Basic 6[/B], which, despite what the "consultants" writing "best practice rules" in the OP think, is in fact an RAII language -- no garbage collection involved at all. Which means that, even in VB6, there's absolutely no reason to set a reference to null. (There are a few gotchas, but not many. I seem to recall that most of them involve COM.)

    Or you could accept that practically all modern languages backed with GC are not mark-and-sweep, but generational. This approach is surprisingly efficient. (It's based on the observable fact that 90+% of objects are short-lived, so you can shift to the next generation and just move the other 10-%). If you've got problems in specific cases, there are usually mechanisms like C#'s "using" construct, which won't do much for your native .NET objects but will allow you to dispose of non-native resources in an RAII way.

    (Of course, if your dimwit architect/boss/pointy-headed whatever insists on stupid rules, you're plumb outta luck. The solution to this is to shoot the middleman, not to shoot the language.)

    I think the thing that most stood out for me, of all the utterly stupid things so beautifully encapsulated in the OP, was the use of "ByVal." I mean. All that effort? And you can't even distinguish between a reference and a value? Niklaus Wirth would piss on you.

    And if you want to make garbage collection "more efficient?" I have the perfect solution for you. Make all variables static.

  • Officer Johnny Holzkopf (unregistered) in reply to cellocgw

    The software engineer does not order another DRY martini, he orders the same one again. Maybe he doesn't get one because martini is NIH...

  • No, Your Name (unregistered)

    "Outsourced" is the biggest WTF.

  • (nodebb)

    Excellent WTF, would facepalm again.

  • (nodebb) in reply to Sole Purpose Of Visit

    I think the thing that most stood out for me, of all the utterly stupid things so beautifully encapsulated in the OP, was the use of "ByVal."

    Made me really wonder. I don't even know the language, but you'd think ByVal would be self-explanatory.

    Vaguely related rant: I curse Fortran for making everything ByRef by default, so you can never trust a subroutine to not change any of its parameters without actually looking up the declaration.

    If a language is going to allow changing variables of the calling scope, I would love them to also requiring this to be declared at the call-site. C# has the out and ref keywords for this. I wish Fortran had the same...

  • SetCommentToNothing (unregistered) in reply to Gamedev

    The .Net JITC and some newish language features to provides hints to it allow for some very light touch GC in C# these days. Check out the "A Different Kind of C#' posts on https://www.bepuentertainment.com/ if you haven't already seen them.

    Yes, like Sole Purpose of Visit says, you can also call out to native code for performance critical parts if you want to. But the performance impact of using .Net is very low if used correctly.

  • para (unregistered)

    So essentially they're doing something for an incorrect reason, incorrectly improving another incorrect solution, and applying the fix in an incorrect manner, such that the incorrect reasoning for the incorrect improvement is incorrectly applied.

  • MiserableOldGit (unregistered)

    This (GC issue) was fixed long before .net lumbered into view, certainly VB6 didn't have the problem, I think it was actually fixed in VB5. Quite a lot of us didd not kick the habit of dereferencing objects for a while because (obviously) we just didn't Microsoft's word for it that they'd actually fixed it!

    It certainly wasn't all objects, I only recall it causing me real problems with the DAO collection.

    No excuse for doing that in .Net though, just lets everyone know you don't understand what's going in.

    I seem to recall parameter defaults switched from passing byref in VB6 to passing byval in .net, I was trying to work out if that could explain the dumbassery of that settonothing method, but it beats me. Unless they got their panties in a bunch over the fact passing a reference to an object byval or byref doesn't protect the object from changes, because it's the reference that's copied not the object. Nope, it's still makes my foot itch.

    In a way it's perfect, appears to do something unnecessary, actually does nothing at all, it'll never fail!

  • Sole Purpose of Visit (unregistered) in reply to MiserableOldGit

    Yup, it never fails. And a thousand unit tests can be written that will always show up green on the dashboards.

    I'd like dashboards/burndown charts/ management splodge to reflect something that is statistically useful.

    But I'm not holding my breath.

  • Simon (unregistered) in reply to SetCommentToNothing

    I don't think the point of calling out to another, non-GC language was to improve performance as such. It can merely have the side-effect of telling the GC "Don't assume that this object can be collected, because it may still be being used on the native side of the fence". Essentially, if you're implementing a bridge by the objects on each side holding some kind of reference to each other, you're in the classic deadly embrace.

    I had this problem with providing a fairly simple Java shim on top of COM objects some years ago. COM objects each include a reference count, then it's trivial to stick a Java interface object on top. But at what point do you decrease the reference count of the COM object? If you're not careful, the heavyweight COM object might not be deleted because there is a reference to it from a Java shim object. What you really want is that the Java shim is, in effect, a weak reference, but things like JNI do not make that easy to enforce at the code level. In practice you have to enforce those rules through coding standards and so on - which I can quite imagine leads to the "null out every object" kind of rule - useful and valid for sharpshooting, but not to be used as a blunderbuss.

  • Simon (unregistered) in reply to Sole Purpose of Visit

    Oh, it's easy to write tests that always pass. The valuable ones are those that occasionally fail. If you can change your code and all your tests still pass, your test suite is not comprehensive enough.

    Total Quality Management etc does not mean "We never machine a part that is defective". It means, "Our quality control is so good, when we machine a defective part, we can detect with near certainty that it is defective". This is actually where things like ISO-9000 are fundamentally of no use to measure product quality - asthey simply measure whether there are processes in place to measure that quality. If the process says "We can produce bad products", you'll get your ISO 9000.... Quis custodiet ipsos custodes?

  • Simon (unregistered) in reply to Sole Purpose of Visit

    Yes. the unattainable goal of "100 percent test coverage", "we test ever function point (method, class, module, whatever...). Testing can only ever be a statistical sample, we hope a useful and representative sample, but this requires some knowledge of statistical methods.

    I've never understood why developers - however good - are expected to write unit tests for their own code. They're the least competent people to do so: one tends to end up with extreme cases of Conway's Law where the test code just mirrors the implementation of the shipped code itself - after all, if you as a developer have written a great piece of code, why are you going to write test code that is by definition inferior to it?

    By all means get another developer at a reasonable distance to write the tests for it, and you as a developer can write tests for another's. I'm not saying you need a huge dedicated QA department mindlessly churning out tests just to meet some arbitrary metric, these "TEST(1 == 1)" types of test.

    But of course, it is very difficult to convince people that a test that always passes carries absolutely zero information (in the Shannon sense). It's a nice warm feeling to see a shallow sea of green after each build... but can the tests call spirits from the vasty deep?

  • Helten (unregistered) in reply to MiserableOldGit

    I think I know what's happened. Quite correctly, ByRef was the default in VB6. In Visual Basic .NET it's ByVal. If you copy and paste a VB6 method that lacks the qualifier into a VB.net code file, Visual Studio adds "ByVal" to the signature. This isn't unreasonable, as Visual Studio can't know if the pasted code is VB6 or VB.NET. I remember running into this problem a number of times myself many years ago while dotnetifying some older code.

  • MiserableOldGit (unregistered) in reply to Helten

    Ah, yes, that makes sense. I was thinking if the code had been jammed through some sort of convertor/upsizer it would have been made explicitly byref everywhere it wasn't declared byval. So this couldn't happen.

    I wasn't thinking copypasta.

    I think within half a day of vb.net exploration I realised there were sufficient differences so even an automatic convertor between vb6 and vb.net needed treating with lots of delicate care. That's why these things need programmers with brains and not robots and "decrees".

Leave a comment on “Nothing But Garbage”

Log In or post as a guest

Replying to comment #:

« Return to Article