• (cs)

    TRWTF is C syntax.

    One of the very few things that VB got right is using a single equal sign as the comparison operator.

    Let the compiler figure out if it's a comparison or assignment based on context.

  • (cs) in reply to Matt Westwood
    Matt Westwood:
    In Java, doing something like:

    if ("TestString".equals(variable)) { : : etc.

    saves on having to test whether variable is null. Do it the other way round and you have to try-catch NullPointerExceptions.

    String.Equals("TestString", variable)
    

    Also evaluates to false if variable is null.

  • foo (unregistered) in reply to DaveK
    DaveK:
    Tasty:
    Yoda followed Altaic grammar, topic-comment-verb, not object-verb-subject. It's a hidden refernce to Japanese martial artists. Now, this is being a know-it-all this being a know-it-all isthis being a it-all-know is!
    FTFY :)
    FYTF
  • foo (unregistered) in reply to DaveK
    DaveK:
    C-Derb:
    Pock Suppet:
    Can we kill this constant == variable pattern, yet?
    Personally, I think that practice is silly and weird to read, and I would be fine with never seeing it again. Remembering to put your constant on the left side of the comparison operator takes as much effort as remembering to use the comparison operator instead of the assignment operator. So why not make the code more readable?
    People who get thrown by the order of arguments to a commutative operator are TRWTF.
    The operator is commutative. Readability not is.
  • foo (unregistered) in reply to C-Derb
    C-Derb:
    Evan:
    Though there is still one case where the C/C++ warning does a better job:
    bool a, b;
    ...
    if (a = b) { ... }
    is, without checking, I think legal C# and Java.
    This ignores the original complaint, which was
    Pock Suppet:
    Can we kill this constant == variable pattern, yet?
    Personally, I think that practice is silly and weird to read, and I would be fine with never seeing it again. Remembering to put your constant on the left side of the comparison operator takes as much effort as remembering to use the comparison operator instead of the assignment operator. So why not make the code more readable?
    And, unlike the = vs. == mixup, I don't know of any compiler warning for variable == constant comparisons in case they forget it once. So in fact, it's not only making the code less readable, but also less reliable, provided you heed compiler warnings. I think that's the last straw.

    I can only conclude this pattern is for those who (or whose managers)

    • didn't think it through,
    • ignore/disable compiler warnings,
    • tie a knot in their handkerchief in order to remind them to look at the knot in their other handkerchief, and/or
    • desperately need rules to follow, however pointless
  • NullIsNotAnObjectBro (unregistered) in reply to JC
    JC:
    SteveThePirate:
    That doesn't make since. If variable is null it is not an object and therefore that method doesn't exist for it.

    You can do that with extension methods in C# as he says. [/code]

    The main problem is we were talking about Java, null in Java is not even an Object.

  • Evan (unregistered) in reply to xaade
    xaade:
    Evan:
    Remy Porter:
    String.replace replaces all instances of a Char or CharSequence (Strings implement CharSequence). String.replaceFirst replaces only the first instance.
    That is a terrible naming scheme.

    No it's not.

    Having "replace" manage to only replace the first instance is not intuitive at all.

    What if someone asked you to buy a dozen eggs, but replace broken eggs, and you only replaced the first broken egg?

    replace"All" should be implied.

    replace"First/Last/Count" should be a specification.

    I don't really care about all/just the first. (I could argue for "just the first" by way of analogy to find(): do you expect s1.find(s2) to return the index of the first match or an array of all of them? But that's me just being devil's advocate. I might like to use replaceFirst and replaceAll for the two string functions.)

    My complaint is how replaceAll is the regex version of replace, rather than being replaceRegex or something.

    C-Derb:
    Remembering to put your constant on the left side of the comparison operator takes as much effort as remembering to use the comparison operator instead of the assignment operator. So why not make the code more readable?
    I'm not a fan of const == var and don't use it, but I do disagree here, quite a bit. You can't really fat-finger 3 == x into x == 3, and even if you did it's a lot easier to notice than x = 3 vs x == 3.
  • Smouch (unregistered) in reply to Pock Suppet
    Pock Suppet:
    if (null == aReceiver) {
      return null;
    }
    if ((null == anOldString) || (null == aNewString)) {
      return aReceiver;
    }
    Can we kill this constant == variable pattern yet? You're not testing the value of null or 3 or PI; you're testing the variable. Object-verb-subject order doesn't grammatically match very many programming languages (or many spoken languages, for that matter), so stop using it! Nao!

    A Yoda-style

    = null anOldString =
    would be perfectly acceptable, however.

    No ! because it's just too easy to assign a null to a variable accidentally with

    if(anOldString=null)...

    Whereas the compiler will scream if you try this

    if(null=anOldString)...
  • (cs)

    Warnings: Warning are a fact of life ("Danger Will Robinson"), and when compiling code, having lots of warnings in a compiler all turned on is akin to having another set of eyes looking at the code. Sure you can program with "rules" and many of us do (formatting, etc.) but some are just plain stupid. If you desire to do the:

    if (1 == q)
    
    construct, feel free. Some of us can do it "both ways". There are some silly rules where "higher ups" want to insure that code doesn't have errors, but while they look good, they frustrate some, and often are unneeded. One such example was to do:
    #define EQ ==
    
    so it look nice in if statements. Of course, one could easily circumvent the intent, and use the proper way, but that would be "wrong".

    It is kinda like measuring productivity using lines of code, or paying bounties for bugs found. Many times such efforts (many articles here!) fail when the participants game the system. That is what is happening here.

    Me: Always a good idea to '-Wall' and see how the chips fall! Unfortunately sometimes it goes a bit far (most compilers are pretty good though!). Just look at a step ladder next time you are in a hardware store and marvel at the warning stickers plastered over the thing. You then remember that EACH one of them was the result of a lawsuit, where a lawyer got rich, and the operator was stupid!

    Moral: Don't be stupid!

  • RocketSigns (unregistered)

    Just in case the original author of this WTF is reading this: Is this from the code base of model driven framework developed by a small, German company based in Düsseldorf, Berlin and Stuttgart? Because I could swear I've seen this code before, just with a ton of other equally weird StringUtil methods.

  • Doug (unregistered) in reply to foo

    The last straw for me was realizing it didn't catch the much more common 'if ( var1 = var2 )' situation (assuming var1 is a modifiable lvalue).

    In other words, the yoda conditional claims to fix a problem, but in reality it only catches a small minority. The correct fix is to:

    1. Train your fingers to put =='s in comparisons and train your eyes to find errors
    2. Teach your compiler to find things when you mess up

    (BTW, those two rules apply to 90% of all debates about code style. Usually, the problem isn't code style; the programmer and the compiler need to grow up a bit.)

  • Nick (unregistered) in reply to gnasher729
    gnasher729:
    eViLegion:
    [Much nicer in C++:
    SomeStringClassThing* aReciever;
    if (!aReciever || (!anOldString || !aNewString))
    {
      return aReceiver;
    }
    

    No bugs or compiler errors.

    I once lost a week of my life because someone who was assumed to be very clever replaced

    if (ptr != NULL)

    with

    if (! ptr)

    without checking the code, without doing a code review, in a place where it caused the maximum possible damage. The reason for the change was that he felt the second way looked more clever. I could have killed him. I should have killed him. Note that unlike the "=" vs. "==" confusion, the compiler has absolutely no chance to give a warning, just like it can't give a warning if you write "ptr == NULL" instead of "ptr != NULL".

    I've programmed in C/C++ for so long that "ptr != NULL" or "ptr == NULL" always makes me look twice, because I'm so used to just "if(ptr)", read as "if ptr", or "if(!ptr)", read as "if no(t) ptr". I've never confused those two but the comparison versions remind me of "if(b == true)" and "if(b != false)" with booleans which is basically the equivalent of ==NULL and != NULL respectively --- huh?

  • (cs) in reply to gnasher729
    gnasher729:
    eViLegion:
    [Much nicer in C++:
    SomeStringClassThing* aReciever;
    if (!aReciever || (!anOldString || !aNewString))
    {
      return aReceiver;
    }
    

    No bugs or compiler errors.

    I once lost a week of my life because someone who was assumed to be very clever replaced

    if (ptr != NULL)

    with

    if (! ptr)

    without checking the code, without doing a code review, in a place where it caused the maximum possible damage. The reason for the change was that he felt the second way looked more clever. I could have killed him. I should have killed him. Note that unlike the "=" vs. "==" confusion, the compiler has absolutely no chance to give a warning, just like it can't give a warning if you write "ptr == NULL" instead of "ptr != NULL".

    OK, yeah, I guess at a glance that !ptr and ptr != NULL look like they might do that same thing, so could cause problems if people have a tendency to compare the pointer to NULL. The thing about re-factoring is you should make sure you actually do it right, and don't completely invert the meaning of things!

    But my point is that by not having any comparison operator at all (eg, either if(ptr){} or if(!ptr){}) then the condition is always clear, and less prone to typos.

    Now of course, you could easily omit the ! by mistake (though no more easily than any other single-character omission), and by doing so completely invert the meaning of the condition, but the simplicity of the syntax is such that you're much more likely to notice and be able to correct it.

    Also, accidentally changing a true to a false (or vice versa) is sort of swapping-like-for-like (at least the type is the same). Therefore it is likely to result in a more natural bug-symptom... e.g. something simply not happening when it should, or happening when it shouldn't.

    Whereas, imagine a conditional which WOULD evaluate to true if without the typo, but which instead mistakenly performs an assignment operation and THEN happens to return true with the typo. This results in a completely unexpected side effect that isn't immediately obvious until later, but possibly doesn't actually manifest itself within the block of code guarded by that erroneous condition. Bad. Bad bad bad bad bad.

  • PRMan (unregistered) in reply to gnasher729
    gnasher729:
    eViLegion:
    [Much nicer in C++:
    SomeStringClassThing* aReciever;
    if (!aReciever || (!anOldString || !aNewString))
    {
      return aReceiver;
    }
    

    No bugs or compiler errors.

    I once lost a week of my life because someone who was assumed to be very clever replaced

    if (ptr != NULL)

    with

    if (! ptr)

    without checking the code, without doing a code review, in a place where it caused the maximum possible damage. The reason for the change was that he felt the second way looked more clever. I could have killed him. I should have killed him. Note that unlike the "=" vs. "==" confusion, the compiler has absolutely no chance to give a warning, just like it can't give a warning if you write "ptr == NULL" instead of "ptr != NULL".

    Yeah, I did something like that once when I was a beginner (haven't we all?). I have now realized that I only clean up files that I am working in for some other reason. Any file I have not opened for what I am working on does not get touched.

  • (cs) in reply to Matt Westwood
    Matt Westwood:
    If your compiler gives you 1000 warnings I rather think you need to go back to Programming 101. Leaving warnings unattended is bone-headed.
    Please apply for a job at my company immediately. We need you. Your profanity-laden rants would fit right in, too.
  • Public Service Announcement (unregistered) in reply to Smouch
    Smouch:
    Pock Suppet:
    if (null == aReceiver) {
      return null;
    }
    if ((null == anOldString) || (null == aNewString)) {
      return aReceiver;
    }
    Can we kill this constant == variable pattern yet? You're not testing the value of null or 3 or PI; you're testing the variable. Object-verb-subject order doesn't grammatically match very many programming languages (or many spoken languages, for that matter), so stop using it! Nao!

    A Yoda-style

    = null anOldString =
    would be perfectly acceptable, however.

    No ! because it's just too easy to assign a null to a variable accidentally with

    if(anOldString=null)...

    Whereas the compiler will scream if you try this

    if(null=anOldString)...
    Dear comment poster,

    as a courtesy to all readers, before posting a new comment, please read the comments already posted, to avoid making the same points that have already been made and refuted.

    Thank you for your attention.

  • shmosel (unregistered)

    TRWTF is using

    if (null == aReceiver)
    instead of
    if (null.equals(aReceiver))

  • foo (unregistered) in reply to eViLegion
    eViLegion:
    OK, yeah, I guess at a glance that !ptr and ptr != NULL look like they might do that same thing, so could cause problems if people have a tendency to compare the pointer to NULL. The thing about re-factoring is you should make sure you actually do it right, and don't completely invert the meaning of things!
    The other thing about refactoring is that you should test afterwards (doh), and the other other thing is to do it automated whenever possible. In this case, it can be done with a regex replace (how fitting today), so if you screw it up, you screw it up everywhere and you'll notice really soon, e.g. (assuming your if-statments are on lines by themselves, as regex can't count parentheses):
    s/if \((.*) != NULL\)$/if (\1)/
    s/if \((.*) == NULL\)$/if (!(\1))/
    

    In fact, I've done regex replacements for cases I knew there were only a handful of places and manual editing would have been faster, just to reduce the chance of subtle errors.

    But my point is that by not having any comparison operator at all (eg, either if(ptr){} or if(!ptr){}) then the condition is always clear, and less prone to typos.
    Full ack, as Nick #412365 put it best.
    Also, accidentally changing a true to a false (or vice versa) is sort of swapping-like-for-like (at least the type is the same). Therefore it is likely to result in a more natural bug-symptom... e.g. something simply not happening when it should, or happening when it shouldn't.

    Whereas, imagine a conditional which WOULD evaluate to true if without the typo, but which instead mistakenly performs an assignment operation and THEN happens to return true with the typo. This results in a completely unexpected side effect that isn't immediately obvious until later, but possibly doesn't actually manifest itself within the block of code guarded by that erroneous condition. Bad. Bad bad bad bad bad.

    For me, it wouldn't mistakenly perform an assignment operation, as compiling with -Wall -Werror it would never get a chance to run, but I assume you're still talking to those ignoring or disabling warnings (who can't be helped anyway IMHO).

  • qbolec (unregistered)

    I remember, that it is quite easy to call a method on null in C++. The only problem is that null obviously has no vtable, so you can not use any virtual method on it. It can be quite useful. Consider how short is a DFS in a BST then: struct Node{ Node * left,right; void dfs(IVisitor * visitor){ if(this){ visitor->visit(this); left->dfs(visitor); right->dfs(visitor); } } };

  • foo (unregistered) in reply to qbolec
    qbolec:
    I remember, that it is quite easy to call a method on null in C++. The only problem is that null obviously has no vtable, so you can not use any virtual method on it. It can be quite useful. Consider how short is a DFS in a BST then: struct Node{ Node * left,right; void dfs(IVisitor * visitor){ if(this){ visitor->visit(this); left->dfs(visitor); right->dfs(visitor); } } };
    I'm no standards lawyer, so I don't know if it's actually legal or just happens to work with some compilers -- according to SO it seems to be the latter.

    Anyway, I'd consider it very bad style and error-prone -- imagine someone adds something, checking, logging, whatever, to the start of dfs(). If all it gives you is to save one "if" like here, I wouldn't bother. If it occurs more frequently, I'd write a free function (which can do the NULL check and then call the actual method) and its interface would say that its parameter may be NULL.

  • Java? (unregistered)

    What java compilers are people using that don't force booleans in if statements?

    The only useful time to do constant == something is in languages where booleans aren't enforced (like C).

    constant.equals is different.

    Captcha: suscipere I have a suscipere that people are bad at languages.

  • (cs) in reply to shmosel
    shmosel:
    TRWTF is using
    if (null == aReceiver)
    instead of
    if (null.equals(aReceiver))

    TRWTF would be an object that is supposed to represent nothingness having a method.

  • shmosel (unregistered) in reply to chubertdev

    Then how about

    if (null != null && null.equals(aReceiver))

  • Evan (unregistered) in reply to foo
    foo:
    qbolec:
    I remember, that it is quite easy to call a method on null in C++.
    I'm no standards lawyer, so I don't know if it's actually legal or just happens to work with some compilers -- according to SO it seems to be the latter.

    Anyway, I'd consider it very bad style and error-prone -- imagine someone adds something, checking, logging, whatever, to the start of dfs(). If all it gives you is to save one "if" like here, I wouldn't bother. If it occurs more frequently, I'd write a free function (which can do the NULL check and then call the actual method) and its interface would say that its parameter may be NULL.

    Agreed with all of the above. Calling an function on null provokes undefined behavior, and even if that's an unlikely one, it is something that can cause incorrect-according-to-you-but-still-correct optimizations. For instance, in the following:

    int * p = ...;
    int x = *p;
    if (!p) {
        ....
    }

    you may find that the compiler will optimize away the if when you turn on optimization. Why? Because the only time the body of the if will run occurs if p is null; but if p is null, then the dereference of it on line 2 will provoke undefined behavior. So it doesn't matter what happens in that case. I think this isn't a terribly popular optimization at this time, but is correct with respect to the standard, which is what you should be writing against unless you have a damn good reason to do otherwise. See this for a description of how this optimization has led to an exploitable security hole in the Linux kernel.

    The compiler could just as correctly optimize other things based on the assumption that this is not null. Either directly -- e.g. it is allowed to assume that your if(this) is redundant and remove the check, always entering the body -- or indirectly, as in the above (which doesn't do anything for your example).

    Doing what qbolec suggests and assuming you can call functions on null is fragile to the addition of virtual, it is fragile to your compiler and optimization settings, it is fragile to other programmers' surprise. Strongly agree it's a bad idea.

  • (cs) in reply to HardwareGeek
    HardwareGeek:
    Matt Westwood:
    If your compiler gives you 1000 warnings I rather think you need to go back to Programming 101. Leaving warnings unattended is bone-headed.
    Please apply for a job at my company immediately. We need you. Your profanity-laden rants would fit right in, too.
    As for the latter, I have usually replaced the telephone receiver back into its cradle before letting rip, in order not to alienate customers (potential or actual).
  • (cs) in reply to shmosel
    shmosel:
    Then how about
    if (null != null && null.equals(aReceiver))

    Let's get super-WTF-ery

    if (null != null & null.equals(aReceiver))
    
  • shmosel (unregistered) in reply to chubertdev
    chubertdev:
    shmosel:
    Then how about
    if (null != null && null.equals(aReceiver))

    Let's get super-WTF-ery

    if (null != null & null.equals(aReceiver))
    

    Must. Turn. It. Off.

    if (null != null & null.equals(aReceiver)) {
        return aReceiver & ~null;
    }
    
  • S (unregistered) in reply to Matt Westwood
    Matt Westwood:
    If your compiler gives you 1000 warnings I rather think you need to go back to Programming 101. Leaving warnings unattended is bone-headed.

    Sounds great in theory. Not so much if you're dealing with a million-line codebase that dates to Java 1.0 - one which triggers warnings on stuff that's since been deprecated, or entire categories of warnings that didn't exist when the code was written. E.g generics in Java 5, or resource cleanups in 7.

    The code may actually be perfectly functional, it just doesn't conform to newer coding standards. The warnings do get fixed over time, but at any point, the entire codebase is going to have a lot of them, and even single files might have many hundreds...

  • Captain Oblivious (unregistered) in reply to DaveK
    DaveK:
    C-Derb:
    Pock Suppet:
    Can we kill this constant == variable pattern, yet?
    Personally, I think that practice is silly and weird to read, and I would be fine with never seeing it again. Remembering to put your constant on the left side of the comparison operator takes as much effort as remembering to use the comparison operator instead of the assignment operator. So why not make the code more readable?
    People who get thrown by the order of arguments to a commutative operator are TRWTF.

    This is what happens when average people program. This is why we can't have nice things.

  • (cs) in reply to shmosel
    shmosel:
    chubertdev:
    shmosel:
    Then how about
    if (null != null && null.equals(aReceiver))

    Let's get super-WTF-ery

    if (null != null & null.equals(aReceiver))
    

    Must. Turn. It. Off.

    if (null != null & null.equals(aReceiver)) {
        return aReceiver & ~null;
    }
    

    Time to end the universe:

       return aReceiver % null;
    
  • ChorroDulce (unregistered) in reply to EvilSnack

    AMEN!

  • (cs) in reply to S
    S:
    Matt Westwood:
    If your compiler gives you 1000 warnings I rather think you need to go back to Programming 101. Leaving warnings unattended is bone-headed.

    Sounds great in theory. Not so much if you're dealing with a million-line codebase that dates to Java 1.0 - one which triggers warnings on stuff that's since been deprecated, or entire categories of warnings that didn't exist when the code was written. E.g generics in Java 5, or resource cleanups in 7.

    The code may actually be perfectly functional, it just doesn't conform to newer coding standards. The warnings do get fixed over time, but at any point, the entire codebase is going to have a lot of them, and even single files might have many hundreds...

    I believe that that is called "technical debt."

    I've made it a personal rule that when I "inherit" a codebase, that's the cleanup. Don't break anything, but don't hide new warnings because there are so many old ones.

  • foo (unregistered) in reply to S
    S:
    Matt Westwood:
    If your compiler gives you 1000 warnings I rather think you need to go back to Programming 101. Leaving warnings unattended is bone-headed.

    Sounds great in theory. Not so much if you're dealing with a million-line codebase that dates to Java 1.0 - one which triggers warnings on stuff that's since been deprecated, or entire categories of warnings that didn't exist when the code was written. E.g generics in Java 5, or resource cleanups in 7.

    The code may actually be perfectly functional, it just doesn't conform to newer coding standards. The warnings do get fixed over time, but at any point, the entire codebase is going to have a lot of them, and even single files might have many hundreds...

    And your compiler doesn't have options to turn off specific sets of warnings, even for features that change between language revisions? Pity!

  • foo (unregistered) in reply to Matt Westwood
    Matt Westwood:
    HardwareGeek:
    Matt Westwood:
    If your compiler gives you 1000 warnings I rather think you need to go back to Programming 101. Leaving warnings unattended is bone-headed.
    Please apply for a job at my company immediately. We need you. Your profanity-laden rants would fit right in, too.
    As for the latter, I have usually replaced the telephone receiver back into its cradle before letting rip, in order not to alienate customers (potential or former).
    Just kidding, please keep up the good cursing, it gets really boring here otherwise.
  • (cs) in reply to foo
    foo:
    DaveK:
    C-Derb:
    Pock Suppet:
    Can we kill this constant == variable pattern, yet?
    Personally, I think that practice is silly and weird to read, and I would be fine with never seeing it again. Remembering to put your constant on the left side of the comparison operator takes as much effort as remembering to use the comparison operator instead of the assignment operator. So why not make the code more readable?
    People who get thrown by the order of arguments to a commutative operator are TRWTF.
    The operator is commutative. Readability not is.
    What you did with that second sentence there is so wrong I am forced to reference <frystare.jpg>:
    • Programs are written in computer languages, not English.
    • The verb "to be" is not an operator and not commutative.
    • Even if it was, what you've done is not equivalent to swapping the "operands", but swapping one operand with the operator. So you haven't done the equivalent of commutating, you've done the equivalent of rewriting in reverse Polish.

    So, nice sarcasm, but completely fails to prove your point.

    In computer programs, which are mathematical constructs, not human language ones, if you are at all thrown by the order of operands to a commutative operator, then it just shows that you don't sufficiently understand the mathematical meaning behind it at a deep level.

  • S (unregistered) in reply to foo
    chubertdev:
    I believe that that is called "technical debt."

    I've made it a personal rule that when I "inherit" a codebase, that's the cleanup. Don't break anything, but don't hide new warnings because there are so many old ones.

    You're right - except that doing so simply isn't an option. Partly because of the time it would require - months for a codebase of this size - and partly because of the risk of exposing customers to unnecessary large-scale code changes. Remember what I said about the code going back to Java 1.0, and guess what the test coverage looks like for most of it. Newer parts have automated tests, certainly - but those are the bits least in need of cleanup...

    foo:
    And your compiler doesn't have options to turn off specific sets of warnings, even for features that change between language revisions? Pity!

    Sure it does. But we usually want the warnings turned on, so we can see what should be fixed when modifying the file. As I said, we do fix warnings when we can - it's just a very slow process, and every Java release tends to introduce a few more.

  • EuroGuy (unregistered) in reply to DaveK
    DaveK:
    In computer programs, which are mathematical constructs, not human language ones, if you are at all thrown by the order of operands to a commutative operator, then it just shows that you don't sufficiently understand the mathematical meaning behind it at a deep level.
    It's the pot and the kettle. It bothers you that it bothers us which order the operands get, so you clearly do have a strong opinion too about the order of operands to a commutative operator.

    I like to think that I do understand the mathematical magic behind the syntax of the progamming language. But at the same time I also observe that my brain processes code that reads like human language quicker and better. I dare claim that having the operands in the "natural" order prevents more problems than it creates.

    I also dare claim that 90% of the people who use the reverse notation don't do it because they sincerely believe it prevents bugs, but more so because it is another way to show that they are 1337 programmers.

    Also, those that understand the programming language well would never confuse = and ==. It never happened to me; at least it has never been proven! So that returns me to the point I made earlier: the reverse notation might be useful for amateur programmers, but they wouldn't be aware about this trick. The seasoned programmers who know it, most likely don't need it.

  • Mike (unregistered) in reply to foo
    foo:
    qbolec:
    I remember, that it is quite easy to call a method on null in C++. The only problem is that null obviously has no vtable, so you can not use any virtual method on it. It can be quite useful. Consider how short is a DFS in a BST then: struct Node{ Node * left,right; void dfs(IVisitor * visitor){ if(this){ visitor->visit(this); left->dfs(visitor); right->dfs(visitor); } } };
    I'm no standards lawyer, so I don't know if it's actually legal or just happens to work with some compilers -- according to SO it seems to be the latter.

    Anyway, I'd consider it very bad style and error-prone -- imagine someone adds something, checking, logging, whatever, to the start of dfs(). If all it gives you is to save one "if" like here, I wouldn't bother. If it occurs more frequently, I'd write a free function (which can do the NULL check and then call the actual method) and its interface would say that its parameter may be NULL.

    The alternative would be

    struct Node{
      Node * left,right;
      void dfs(IVisitor * visitor){
          visitor->visit(this);
          if(this->left)
           left->dfs(visitor);
          if(this->right)
           right->dfs(visitor);
        }
      }
    };
    
    But in the C world you'd be perfectly fine with
    void dfs(struct Node *this, IVisitor *visitor) {
      if(this) {
        visitor->visit(this)
        dfs(this->left, visitor);
        dfs(this->right, visitor);
      }
    }
    

    and there is probably no C++ compiler in existence (nor will there ever likely be one) in which nonvirtual methods won't work on null object pointers, so maybe the standard should've specified this case explicitly: In p->m(), if m is nonvirtual, p must not be dereferenced. Ditto for p.m. (Although p.x being the offset of x when x is not a method and p is null, might be going a bit too far... despite that being the interpretation taken by almost all compilers too.)

  • vlad (unregistered) in reply to Lothar

    apache commons-lang, version 1.0 (released 2002-10-04) features the method StringUtils.replace(java.lang.String text, java.lang.String repl, java.lang.String with) ("Replace all occurances of a string within another string.")

    http://commons.apache.org/proper/commons-lang/javadocs/api-1.0/org/apache/commons/lang/StringUtils.html#replace(java.lang.String, java.lang.String, java.lang.String)

  • augue (unregistered) in reply to C-Derb
    C-Derb:
    Didn't you mean
    return null == o;
    See how stupid that notation is? Even in a debate about the merits of that pattern, it is just simply more natural to write myVar == conditionalValue.

    Debate over.

    JC never argues for that ordering in the first place. You can't claim "debate over" just because one person happens to agree with you.

  • foo (unregistered) in reply to Mike
    Mike:
    and there is probably no C++ compiler in existence (nor will there ever likely be one) in which nonvirtual methods won't work on null object pointers,
    Unless it's an optimizing compiler, see #412381. This is about C, but can be directly applied to our C++ case.
    so maybe the standard should've specified this case explicitly: In p->m(), if m is nonvirtual, p must not be dereferenced. Ditto for p.m.
    Sure, it could be done, but why make a special exception in the standard for something which still is (IMHO) very bad style in the first place.
  • foo (unregistered) in reply to EuroGuy
    EuroGuy:
    I like to think that I do understand the mathematical magic behind the syntax of the progamming language. But at the same time I also observe that my brain processes code that reads like human language quicker and better. I dare claim that having the operands in the "natural" order prevents more problems than it creates.
    Well put.

    I do think that I understand the mathematics of programming languages either way, but it's just about better readability. For the same reason, I prefer a function to be called replaceAll rather than x28g756q though mathematically, of course, there's no difference.

    FTR @DaveK, my "Readability not is." was just meant as a quick joke. I didn't expect a rigorous mathematical and ligustic analysis. For thanks, aynway biting.

  • Mozzis (unregistered) in reply to Pock Suppet

    Stupid pedantic objection to a practice that avoids the common error of using '=' when you meant '==', thus avoiding the potential for some devilishly subtle bugs.

  • foo (unregistered) in reply to Mozzis
    Mozzis:
    Stupid pedantic objection to a practice that avoids the common error of using '=' when you meant '==', thus avoiding the potential for some devilishly subtle bugs.
    Very subtle, unless you use a modern compiler with warnings, or bother to fucking read the previous comments before making a point already refuted yesterday.
  • Jonathan Wilson (unregistered)

    Some code I work on (C++) has its own string class. But that's because C++ strings suck (or they did back when this code was originally created) and because its a project where all the extra overhead and crap in C++ strings (a lot of which is mandated by the C++ standards) would get in the way. But unlike the examples I see on TDWTF, our class is the exact opposite of a WTF. Neat. Clean. Uses C & C++ string functions where doing so makes sense.

  • trololo (unregistered)

    This is what happens when you come from a C background where you would implement event the most basic function.

  • C-Derb (unregistered) in reply to EuroGuy
    Mozzis:
    Stupid pedantic objection to a practice that avoids the common error of using '=' when you meant '==', thus avoiding the potential for some devilishly subtle bugs.
    No, using '=' when you meant '==' is not that common. Pay attention to the code you are writing.
    EuroGuy:
    I also dare claim that 90% of the people who use the reverse notation don't do it because they sincerely believe it prevents bugs, but more so because it is another way to show that they are 1337 programmers.
    This!
  • Evan (unregistered) in reply to DaveK
    DaveK:
    In computer programs, which are mathematical constructs, not human language ones, if you are at all thrown by the order of operands to a commutative operator, then it just shows that you don't sufficiently understand the mathematical meaning behind it at a deep level.
    Like I said in my last post, I am not a fan of 'const == var' and don't use it. But I think this argument is dumb too.

    The error the 'const == var' idiom is intended to prevent has nothing to do with commutativity. Commutativity is a red herring. It's trying to prevent you from accidentally substituting (and not noticing the substitution of) a completely different, non-commutative operator.

    In other words, no one is saying that 5 == x is easier to write, read, or understand than x == 5.

    The argument is that, first, x == 5 vs x = 5 is hard to miss and, second, that reversing it to 5 = x is the right way of preventing that bug.

    (I'm not sure how much I agree with the first one and definitely disagree with the second for a bunch of reasons.)

  • (cs) in reply to eViLegion
    eViLegion:
    Also... who the hell uses the indefinite article at the start of variable/parameter names? Baffling.

    I do. I use it to mean the entity of a particular type that is under consideration. This is useful when there may be others.

    Sincerely,

    Gene Wirchenko

  • (cs) in reply to EuroGuy
    EuroGuy:
    Any programmer who is pedentic enough to use the Yoda style, is probably also professional enough not to confuse = and ==.

    It is not a matter of confusing them. It is just too easy to make a mistake and miss entering one of the equals signs. Why not make it easy to catch the error?

    I think that the reverse style is ugly, but it does do what it has to. C should not have redefined the = operator, but it is the world we live.

    Sincerely,

    Gene Wirchenko

Leave a comment on “Stringing a Replacement”

Log In or post as a guest

Replying to comment #:

« Return to Article