Lucky Pointing

« Return to Article
  • Severity One 2012-07-24 09:11
    TRWTF is pointers.
  • rjb 2012-07-24 09:14
    I'm not going to lie, though I'd never append a null to the end of a string just for shits and giggles, programming in C++, especially with third party libraries, is often an exercise in frustration with regard to pointers, and the path of least resistance is to just try each pointer/object operator and go with whatever compiles properly.
  • Sebastian Buchannon 2012-07-24 09:14
    Severity One:
    TRWTF is pointers.


    actually no
  • ipeet 2012-07-24 09:22
    Something is fishy here. That code wouldn't make it past the type checker.
  • DonaldK 2012-07-24 09:25
    So what's the problem then?

    ;-)

  • TheSHEEEP 2012-07-24 09:25
    ipeet:
    Something is fishy here. That code wouldn't make it past the type checker.


    Disabled warnings. :D
  • Cbuttius 2012-07-24 09:43
    That code is valid C++ assuming that Buffer is a member variable of type char *.

    The real WTF is that they are implementing their own string class, albeit that what they are trying to do there is not possible with std::string which has no function to return you a writable buffer.

    However that is still a WTF as they should at least interpret it internally as a std::vector<char>

    The +'\0' is stupid, of course but the compiler probably just strips it out.

    Of course it will not put a null terminator on the end of your array. Doing so would be wrong anyway. What would happen if you call this multiple times?


  • Cbuttius 2012-07-24 09:44
    TheSHEEEP:
    ipeet:
    Something is fishy here. That code wouldn't make it past the type checker.


    Disabled warnings. :D


    You probably won't get a warning here though. You normally get a "possible loss of data" when converting from a larger integral type to a smaller one but converting from char to int does not risk any loss of data.

  • Is a good name 2012-07-24 09:54
    Depending on how -> and + are overloaded, this might indeed do exactly what the programmer intended to do...
  • mb 2012-07-24 09:58
    rjb:
    I'm not going to lie, though I'd never append a null to the end of a string just for shits and giggles, programming in C++, especially with third party libraries, is often an exercise in frustration with regard to pointers, and the path of least resistance is to just try each pointer/object operator and go with whatever compiles properly.


    Seriously? I always thought that C++ is precisely the type of language where you can shoot your self in the foot spectacularly with such attitude. I mean like


    bool * myBool = new bool;
    *myBool = true;
    if (myBool) {
    printf("It works, hence the condition on the line above is obviously correct!");
    }
  • beendoingthistoolong 2012-07-24 09:59
    TRWTF is returning char* not const char*, right?

    It seems an odd representative line to me. The compiler almost certainly just drops the +0 operation as redundant and it all works fine. Yes, the author clearly didn't get it, but this is pretty common with part-time or new c++'ers.

    Operator overloading is pretty evil in general, but this would have been more useful generally with:

    const char * String::operator const char *()
    { return buffer; }

    (or even char *)
  • SeySayux 2012-07-24 10:04
    beendoingthistoolong:
    TRWTF is returning char* not const char*, right?

    It seems an odd representative line to me. The compiler almost certainly just drops the +0 operation as redundant and it all works fine. Yes, the author clearly didn't get it, but this is pretty common with part-time or new c++'ers.

    Operator overloading is pretty evil in general, but this would have been more useful generally with:

    const char * String::operator const char *()
    { return buffer; }

    (or even char *)


    Actually...


    #if __cplusplus >= 201103L
    #define EXPLICIT explicit
    #else
    #define EXPLICIT
    #endif

    EXPLICIT String::operator const char*() const {
    return buffer;
    }
  • Cbuttius 2012-07-24 10:21

    class String
    {
    private:

    class Impl
    {
    mutable vector< char > buf;
    public:
    char * operator+( char ch ) const
    {
    buf.push_back( ch );
    return &buf[0];
    }
    };

    Impl Buffer;
    };

  • paquetted 2012-07-24 10:25
    I love pointers so much! And strings!

    But indeed, when you don't master it, it can lead to big WTF!! Like this one... Or like some in the code I have to maintain...
  • History Teacher 2012-07-24 10:32
    Severity One:
    TRWTF is pointers.

    ...are you the author of this particular representative line, by any chance?

    TRWTF are coders who don't understand pointers, yet touch any language less separated from hardware than crossplatform HTML+javascript.
  • Severity One 2012-07-24 10:39
    History Teacher:
    Severity One:
    TRWTF is pointers.

    ...are you the author of this particular representative line, by any chance?
    No.

    History Teacher:
    TRWTF are coders who don't understand pointers, yet touch any language less separated from hardware than crossplatform HTML+javascript.
    Oh, I understand pointers, but they are too easy to muck up, especially with C++'s Byzantine syntax, and an object-oriented language offers enough tools to pretend that pointers do not exist (such as Java does). Unless you're doing serious low-level or high-performance computing, there isn't much use for pointers.
  • java.lang.Chris; 2012-07-24 10:46
    Seeing that attempt at "string concatenation" leaves me with the feeling that Benedikt's predecessor may have been a Java programmer.

    Of course, TRWTF is C++. It could have been an elegant and simple object oriented superset of C, but instead it's a glorious example of how not to design a programming language. In fact, I'm not entirely sure this is a joke:

    http://www-users.cs.york.ac.uk/~susan/joke/cpp.htm

    The other RWTF is Akismet
  • Dave-Sir 2012-07-24 10:48
    Cbuttius:
    TheSHEEEP:
    ipeet:
    Something is fishy here. That code wouldn't make it past the type checker.


    Disabled warnings. :D


    You probably won't get a warning here though. You normally get a "possible loss of data" when converting from a larger integral type to a smaller one but converting from char to int does not risk any loss of data.

    You won't get any warning, but not for the reasons you state.

    The type of '\0' is int. Assuming buffer is a pointer to char, adding an int to a pointer is a perfectly valid operation, and not worthy of a warning.

    It reminds me of some code I encountered some years ago. To test fo an odd number, the following code was used:

    if (value&1 == 1) <etc.>

    However, because of precedence rules, this gets parsed as

    if (value & (1==1))

    But it still works. Just not the way the original programmer thought.
  • RandomUser423718 2012-07-24 10:53
    Severity One:
    Oh, I understand pointers, but they are too easy to muck up, especially with C++'s Byzantine syntax, and an object-oriented language offers enough tools to pretend that pointers do not exist (such as Java does). Unless you're doing serious low-level or high-performance computing, there isn't much use for pointers.
    BOCTAOE

    When referring to "physical memory" pointers, maybe. However pointers, as a concept, are important for understanding any number of common patterns, such at those that appear in relational databases (primary/foreign keys), etc.
  • Cbuttius 2012-07-24 10:54
    Calling a pointer a reference doesn't mean it is not a pointer.

    Java has pointers. They call them references and use . syntax instead of -> but they have the semantics of pointers.

    You don't have to delete them because Java has automated garbage collection.

    That is why if you don't assign one to anything then try to use it you get a NullPointerException.

    Remember that C++ was originally a layer on top of C that brought in some concepts from other OO languages that were there at the time, and one of the main important things supported is RAII which essentially means cleaning up through objects' automatic destructors.

    That is why, if you use the string class, you don't have to mess about with pointers.

    But yes, you can integrate with C easily which means if there is a library in C you can just use it. So sometimes you need to get a C string out of your "managed" classes. If you want a contiguous writable buffer you should use vector<char> underneath, not std::string. The overload of operator+ in my example was a bit of a joke though. If you are going to give it operator+ it should have the proper semantics of that operator so.


    String operator+( String const& s, char ch )
    {
    String s2( s );
    s2.append(ch); # or push_back or +=
    return s2;
    }


    Yes, operator+ returns a new object and leaves the old object in an unchanged state.

    As long as you obey the spirit of the rules of operators when you overload them, users of your class won't get into trouble. It is true that doing the above a lot will be inefficient but then you won't be doing that as to build strings you use ostringstream.
  • Jack 2012-07-24 10:57
    Dave-Sir:
    However, because of precedence rules
    Precedence? WTF is precedence? That looks like a Very Big Word. I should not have to know it. I should not have to know anything. The computer should just do what I want.

    Programming languages are TRWTF. Nobody wants to type commands. So boring. And hard, dammit! There should just be a big round candy colored button and when I click it, it reads my mind and Just Works. If you can't design something to cater to my fantasy, you are no good.
  • rjb 2012-07-24 11:04
    Perhaps I misworded what I said. What I meant was compiles properly, and exhibits the desired behavior. If it doesn't exhibit the desired behavior, then I wouldn't say it compiled properly, it just compiled. :p
  • ¯\(°_o)/¯ I DUNNO LOL 2012-07-24 11:20
    DonaldK:
    So what's the problem then?
    Rolling your own String class?

    Oh wait, I know... it needs a regex!

    Actually, TRWTF is operator overloading.
  • Steve The Cynic 2012-07-24 11:37
    java.lang.Chris;:
    Seeing that attempt at "string concatenation" leaves me with the feeling that Benedikt's predecessor may have been a Java programmer.

    As opposed to a colleague of mine at a previous job of mine, who had been doing too much work with JavaScript.

    So, to present a message like "Elements found: {number}", he would exploit JavaScript's unnatural fascination with automatic type conversions:
      var value = calculationFunction( parameters );
    
    var message = "Elements found: " + value;

    This doesn't work so well in C++.
  • Ross 2012-07-24 11:41
    This code is painful to look at on so many levels. TRWTF is that, given the pointer from this function, the calling code can mess with the data in the object without, presumably, any data length or integrity checking.

    Encapsulation? We don't need no stinkin' encapsulation!
  • Zolcos 2012-07-24 11:46
    Heh. It's so rare for us to see C++ WTFs on this site that when one is finally posted, most of the comments focus on generalities about the language itself.
  • Ross 2012-07-24 11:50
    I love Stroustrup's quote:

    "There are only two kinds of languages: the ones people complain about and the ones nobody uses."
  • java.lang.Chris; 2012-07-24 12:03
    Steve The Cynic:

    As opposed to a colleague of mine at a previous job of mine, who had been doing too much work with JavaScript.

    So, to present a message like "Elements found: {number}", he would exploit JavaScript's unnatural fascination with automatic type conversions:
      var value = calculationFunction( parameters );
    
    var message = "Elements found: " + value;

    This doesn't work so well in C++.


    Sadly, there's a lot of odd code that a C++ compiler will happily compile:


    [chris@titwank ~]$ cat ouch.cpp
    #include <iostream>
    #include <string>

    using namespace std;

    int
    main()
    {
    string s = "Are we having fun yet?";
    int value = 0xdeadbeef;
    cout << s.c_str() + value << endl;
    return 0;
    }
    [chris@titwank ~]$ c++ -o ouch ouch.cpp
    [chris@titwank ~]$ ./ouch
    Segmentation fault (core dumped)

  • Bartholemew Taps 2012-07-24 12:08
    This one brings to mind adages such as "there's never time to do it right but there's always time to do it over", or more succinctly "measure once cut twice; measure twice cut once".

    The problem is that people get nervous about the idea of trying to do something properly (in this case checking the types). But the prospect of guessing and hoping seems less nervous.

    It seems back-to-front, but it's not surprising if you follow a rule of higher risk -> lower outlay. Since writing software seems risky to such people, they minimise their outlay i.e. the amount of time they spend on the first coded version.

    Of course, experience of doing it the "right way" would help them realise that they can drive down the risk by using good processes.
  • Cbuttius 2012-07-24 12:10
    Using the null character to denote end of string has its advantages but can be a WTF at times.

    Prefixing the length means it is faster to calculate the length of the string but makes it less maintainable. Firstly the potential length of the string is limited by the length of its header, and secondly when you modify the string you have to modify this length.

    In addition, there is the method of "tokenising" a string that into lots of strings by modifying the "separator" character into a null, allowing each component to be a string on its own. In fact sometimes you use a double zero to indicate the end of the sequence.

    Of course for binary "blobs" there will often be embedded null characters but in general these are not modified or lengthened the same way strings often are.

    The real WTF with C++ and strings is that the standard string is:
    1. really a typedef of template basic_string<char, char_traits<char>, allocator<char> >
    2. No standard ABI so if your library uses std::string in its interface it isn't guaranteed to work with a different library that uses a different compiler.

    It wasn't that long ago that you couldn't even pass a std::string between DLLs / shared objects built with the same compiler.

    All of which leads to you finding lots of "own implementations" of string, especially in legacy code.

    Of course, legacy code is still around because people still use these projects that are being maintained and they brought in enough money to the business.

  • ericmorton 2012-07-24 12:11
    I'm surprised no one said:

    "First\0"
  • Mason Wheeler 2012-07-24 12:13
    java.lang.Chris;:
    Seeing that attempt at "string concatenation" leaves me with the feeling that Benedikt's predecessor may have been a Java programmer.

    Of course, TRWTF is C++. It could have been an elegant and simple object oriented superset of C, but instead it's a glorious example of how not to design a programming language.


    That's been tried. It's called Objective-C, and it's such a smelly pile of WTF that no one uses it unless Apple is stuffing it down their throats.

    Is it even possible to create an elegant and simple superset of something that it itself neither elegant nor simple? C++ may be a glorious example of how not to design a programming language, but it got half of its mess from C and most of the other half is hacks to try to make it possible for higher-level concepts to integrate properly onto the existing C foundation.
  • lucidfox 2012-07-24 12:14
    TRWTF is rolling out their own string implementation.

    You know, as if C++ doesn't have enough of these already.
  • Cbuttius 2012-07-24 12:17
    ericmorton:
    I'm surprised no one said:

    "First\0"


    Because in C++ you start counting from 0.

    So the first post should read:

    0th...
  • Asdlarfgs 2012-07-24 12:17
    Steve The Cynic:

    So, to present a message like "Elements found: {number}", he would exploit JavaScript's unnatural fascination with automatic type conversions:
      var value = calculationFunction( parameters );
    
    var message = "Elements found: " + value;


    How... how is that "exploiting JavaScript's unnatural fascination with automatic type conversions"? That's just the natural way to do it in most dynamic languages.
  • Cbuttius 2012-07-24 12:21
    lucidfox:
    TRWTF is rolling out their own string implementation.

    You know, as if C++ doesn't have enough of these already.


    It depends if they actually do need to get a char * out of it (rather than a const char *) in which case you can't do it with std::string.

    But in this case your implementation should use std::vector<char> underneath and not raw pointers.

    However if you handle a lot of very short strings, there is an advantage in using a "local" member class buffer to handle short strings rather than allocate as allocations are expensive. In such a case you will probably have a member function to get the data buffer.

  • Dan 2012-07-24 12:32
    Bartholemew Taps:
    measure once cut twice; measure twice cut once
    I hired a contractor to do some remodeling and learned, to my great dismay, chagrin, and expense, that his philosophy was "measure zero, cut three times".

    He actually installed a door frame, forgot to account for the thickness of sheetrock, tore it out, installed it again a half inch down, realized he forgot to account for the trim, tore it out again, installed it again, and it was still wrong. I forget why this time.

    I wanted to fire him but he had me by the balls. That part, he was really good at.

    Years later, I still curse his memory every time I walk down my crooked hallway. He also left me with a ceiling that slopes, and a roof that doesn't. All because he was fundamentally averse to a measuring tape and simple addition.

    Remodeling is hell. Stay as far away as you can.
  • iToad 2012-07-24 12:33
    It would be amusing to run the source code through PC-lint, and see just how many other issues like this are lurking deep in the code.
  • Stev 2012-07-24 12:36
    TRWTF is people complaining that a language "lets you shoot yourself in the foot". A gun will let you shoot yourself in the foot, much like a hammer will let you smash your thumb and a saw will let you cut your fingers off. C++ is a tool like any other and will cause a bloody mess if used without proper training or care, or if used in an inappropriate situation.

    You wouldn't use a chainsaw to slice a lemon in a cramped kitchen, nor would you use a carving knife to cut down a tree. C++ is no different - it has its place and where it is used appropriately it is positively unmatched. Likewise, when used inappropriately it'll cause massive amounts of bloodshed.

    The same can be said for just about any language. Deal with it.
  • java.lang.Chris; 2012-07-24 12:38
    Mason Wheeler:
    java.lang.Chris;:
    Of course, TRWTF is C++. It could have been an elegant and simple object oriented superset of C, but instead it's a glorious example of how not to design a programming language.


    That's been tried. It's called Objective-C, and it's such a smelly pile of WTF that no one uses it unless Apple is stuffing it down their throats.


    I actually like Objective-C, since it essentially combines my two favourite programming languages - Smalltalk and C. Compared to C++ it feels much more intuitive once you get past the culture shock of seeing so many square brackets.

    Mason Wheeler:
    Is it even possible to create an elegant and simple superset of something that it itself neither elegant nor simple? C++ may be a glorious example of how not to design a programming language, but it got half of its mess from C and most of the other half is hacks to try to make it possible for higher-level concepts to integrate properly onto the existing C foundation.


    I'd argue that C++ is largely a WTF of it's own making, since it's not a strict superset of C so it can't really blame it's forebear, and got a lot of things wrong in the object model and the standard library. I'd have preferred virtual methods by default, and for dubious "experiments" such as vectors of bools to have not made it into the standard. That's just scratching the surface - for more WTF'ery, refer to the Exceptional C++ and Effective C++ books.
  • iWantToKeepAnon 2012-07-24 12:40
    Buffer could very well be a class that has overloaded the plus operator. The real WTF is operator overloading so that you can never really know what is going on.

    This is just more postings by code snobs. Come on, let's get back to the really gross stuff and stop complaining about people's syntax. :-[
  • Zecc 2012-07-24 13:12
    rjb:
    the path of least resistance is to just try each pointer/object operator and go with whatever compiles properly.
    Some of us can think faster than the code compiles.
  • jMerliN 2012-07-24 13:43
    Is a good name:
    Depending on how -> and + are overloaded, this might indeed do exactly what the programmer intended to do...


    TRWTF is operator overloading. When the language constructs are user-defined, everything is WTF.
  • n_slash_a 2012-07-24 13:48
    Stev:
    TRWTF is people complaining that a language "lets you shoot yourself in the foot". A gun will let you shoot yourself in the foot, much like a hammer will let you smash your thumb and a saw will let you cut your fingers off. C++ is a tool like any other and will cause a bloody mess if used without proper training or care, or if used in an inappropriate situation.

    You wouldn't use a chainsaw to slice a lemon in a cramped kitchen, nor would you use a carving knife to cut down a tree. C++ is no different - it has its place and where it is used appropriately it is positively unmatched. Likewise, when used inappropriately it'll cause massive amounts of bloodshed.

    The same can be said for just about any language. Deal with it.

    Well stated. This is why a good company (should) hire engineers and not half-trained monkeys.
  • pitchingchris 2012-07-24 14:11
    Ross:
    I love Stroustrup's quote:

    "There are only two kinds of languages: the ones people complain about and the ones nobody uses."


    We need a 'like' or thumbs up button in here
  • pitchingchris 2012-07-24 14:16
    jMerliN:
    Is a good name:
    Depending on how -> and + are overloaded, this might indeed do exactly what the programmer intended to do...


    TRWTF is operator overloading. When the language constructs are user-defined, everything is WTF.


    I disagree. There are plenty of useful things you can do with operater overloading. Performing math on data types so you can add matrices together with operaters. Its up to the programmer to be smart about it and implement it in a sensible way (and document it)
  • danbruc 2012-07-24 14:46
    Cbuttius:
    Calling a pointer a reference doesn't mean it is not a pointer.
    That's not true. In C# there is a single thing you can do with a reference - dereference it. A reference is either a null reference or a reference to an object of its specific type. You are neither allowed to use pointer math to point to the interior of an object or to random garbage in memory, nor are you allowed to cast a reference to an arbitrary type without generating at least an invalid cast exception at runtime (unless the cast is valid of course).
  • Harrow 2012-07-24 15:08
    Cbuttius:
    ...put[ting] a null terminator on the end of your array... would be wrong anyway. What would happen if you call this multiple times?
    Two null terminators indicates the end of a string list or the end of a paragraph. Three nulls indicates the end of a document or file. Four nulls is end of directory, Five nulls is end of transmission or end of volume, and six nulls stands for the end of the working day.

    Seven nulls marks end of current employment. Eight nulls means time to retire and collect SS. Nine nulls specifies the end of the world as we know it.

    So calling it a few extra times may generate errors, which will probably be recoverable, but if you call it inside an infinite loop, it's curtains for all of us.

    Please use null terminators responsibly.

    -Harrow.
  • Zylon 2012-07-24 15:36
    pitchingchris:
    I disagree. There are plenty of useful things you can do with operater overloading.

    But is there anything you can do with operator overloading that you can't do without it? Y'know, other than making your code harder to decipher for maintenance programmers? Operator overloading always seemed like self-indulgent syntactic sugar to me.
  • jMerliN 2012-07-24 16:17
    Stev:
    TRWTF is people complaining that a language "lets you shoot yourself in the foot". A gun will let you shoot yourself in the foot, much like a hammer will let you smash your thumb and a saw will let you cut your fingers off. C++ is a tool like any other and will cause a bloody mess if used without proper training or care, or if used in an inappropriate situation.

    You wouldn't use a chainsaw to slice a lemon in a cramped kitchen, nor would you use a carving knife to cut down a tree. C++ is no different - it has its place and where it is used appropriately it is positively unmatched. Likewise, when used inappropriately it'll cause massive amounts of bloodshed.

    The same can be said for just about any language. Deal with it.


    Your analogies are flawed. Any Turing complete language can let you shoot yourself in the foot. See: algorithmic complexity, bad code, etc. You compare a tool to a tool that has hidden tool-altering features that are invisible except on extreme introspection.

    The kind of "shoot yourself in the foot" C++ brings to the table is more like selling a gun to people and making it such that any person can modify where the bullet exits in a non-obvious manner (such as, it still looks like a gun but when you pull the trigger, it shoots directly at your feet). Then whenever you pick up a gun you haven't been the sole-owner and sole-possessor for its lifetime, you can't ever for sure know when you pull the trigger that it's not going to shoot your foot, unless you take it apart. Oh, and C++ also lets you universally modify how guns work, so anyone can just change how they fire, so now you have to deconstruct the entire universe to figure out if your gun will shoot you in the foot when fired.

    That's the WTF of C++. Changing the language's behavior in a manner that isn't immediately apparent without further introspection. And this breeds WTFs not present in other languages: APIs designed to be used via overloaded operators, so that there's not a well named function you can call to do a task (and thus avoid the use of operators with non-primitives, and again, you can overload operators on primitives, too, which is a whole other world of WTF). Things like needing to call myObj.operator++(...) explicitly to increment something because there's not a myObj.increment(). People do this. The very existence of this terrible feature leads to feature abuse and then feature reliance. We don't have the issues this "feature" causes in other languages. When we see code pasted in StackOverflow, we know what it does, not what it should do given the default operators.

    It's more like a hammer that has the "feature" of being able to have an invisible spring attachment so that when you hammer a nail, the hammer flies back into your face. It's not just a regular hammer, it's now an overloaded hammer, and one can argue the merits of such a hammer (two nails at once, if you position them right), but at the end of the day, it's still a massive WTF. It's novel, sure, but that doesn't make it any less of a WTF.
  • someone 2012-07-24 16:19
    Everyone can do that with C++

    But with languages like Pascal, you have no chance
  • History Teacher 2012-07-24 17:05
    Severity One:

    History Teacher:
    TRWTF are coders who don't understand pointers, yet touch any language less separated from hardware than crossplatform HTML+javascript.
    Oh, I understand pointers, but they are too easy to muck up, especially with C++'s Byzantine syntax, and an object-oriented language offers enough tools to pretend that pointers do not exist (such as Java does). Unless you're doing serious low-level or high-performance computing, there isn't much use for pointers.

    Fair 'nuff. But even Java handles are pointers, Java is just really good at preventing you from having invalid values. Pointer is what makes a von Neuman architecture computer (or virtual machine), it's not a WTF.

    But yeah, first post and all that, never mind :)
  • History Teacher 2012-07-24 17:18
    Zylon:
    pitchingchris:
    I disagree. There are plenty of useful things you can do with operater overloading.

    But is there anything you can do with operator overloading that you can't do without it? Y'know, other than making your code harder to decipher for maintenance programmers? Operator overloading always seemed like self-indulgent syntactic sugar to me.

    Do not underestimate syntactic sugar. There are concepts which make no sense to incorporate into the core language, yet natural way of operating on them is with operators, and being forced to use method call syntax creates just horrible looking, hard to understand code.

    But operator overloading in certainly something, which should not be used without careful design. As such, using it should be limited to well-documented libraries, and in actual application they should be used only as documented in the library. If it's not worth designing and documenting that carefully, then better use normal methods with self-documenting names. In C++, same applies to templates.
  • Michael 2012-07-24 17:37
    rjb:
    I'm not going to lie, though I'd never append a null to the end of a string just for shits and giggles, programming in C++, especially with third party libraries, is often an exercise in frustration with regard to pointers, and the path of least resistance is to just try each pointer/object operator and go with whatever compiles properly.
    Oh dear! I have often suspected many people program that way, but (as with ANY OTHER PROGRAMMING CONCEPT) if you don't understand it, don't use it. If you NEED to use it, LEARN it!!

    Pointers are not hard (except when you first start - but I suspect this is largely just because they overwhelm people. One day you have that 'aha' moment where suddenly the difference between * and & (and . and ->) make sense. If this doesn't happen within a month of using C/C++, get a job using a different language....).
  • Urad 2012-07-24 17:54
    Severity One:
    History Teacher:
    Severity One:
    TRWTF is pointers.

    ...are you the author of this particular representative line, by any chance?
    No.

    History Teacher:
    TRWTF are coders who don't understand pointers, yet touch any language less separated from hardware than crossplatform HTML+javascript.
    Oh, I understand pointers, but they are too easy to muck up, especially with C++'s Byzantine syntax, and an object-oriented language offers enough tools to pretend that pointers do not exist (such as Java does). Unless you're doing serious low-level or high-performance computing, there isn't much use for pointers.
    You just made me cry.

    I work with people all day who have never seen anything other than C# and/or Java. In itself, this is no biggie, but I cringe at how wastefully they create Objects simply because they don't seem to understand the work being done under the hood (whatever people think about C or C++ having to explicitly create and destroy objects (or allocate/free memory in C's case) gives you an understanding that there is effort involved. Simply forgetting about a reference we don't need any more promotes an attitude that the resources don't matter). Granted, you don't have to understand pointers per se' to understand the work being done, but I think it is important that people do at least a semester or two in a low-level language so they understand what is actually going on. I think one of the real problems with many of today Graduates in IT disciplines is that they are too willing to let the compiler optimize away their bad habits.

    One of the examples I saw recently was a 'programmer' who implemented a small bitfield (4 bits) as a String in C# (and I was a bit concerned when I pointed out it might not be the best way to do it, a more senior programmer disagreed).

    A common argument I hear is "It doesn't matter, because we have so much memory and/or CPU available". When we're making a Desktop Sudoku solver this is probably true. When we're making an app that has to support multiple users querying a large database and returning results in realtime then you start to realise the importance of minimising resource consumption. (More frighteningly, when we had serious performance issues after a poor change on a fairly reasonably specced server, I was appalled that the common voice (even from people within IT) was "Throw more CPU at it")
  • AGray 2012-07-24 17:54
    java.lang.Chris;:
    Sadly, there's a lot of odd code that a C++ compiler will happily compile:


    [chris@titwank ~]$ cat ouch.cpp
    #include <iostream>
    #include <string>

    using namespace std;

    int
    main()
    {
    string s = "Are we having fun yet?";
    int value = 0xdeadbeef;
    cout << s.c_str() + value << endl;
    return 0;
    }
    [chris@titwank ~]$ c++ -o ouch ouch.cpp
    [chris@titwank ~]$ ./ouch
    Segmentation fault (core dumped)



    I am TRWTF - I do not follow (exactly) what's happening here. I can see the bit where that hex offset is added to the output stream. I'm not sure how this causes a Segmentation fault...explanation please?
  • AWP 2012-07-24 18:13
    Jack:
    Dave-Sir:
    However, because of precedence rules
    Precedence? WTF is precedence? That looks like a Very Big Word. I should not have to know it. I should not have to know anything. The computer should just do what I want.

    Programming languages are TRWTF. Nobody wants to type commands. So boring. And hard, dammit! There should just be a big round candy colored button and when I click it, it reads my mind and Just Works. If you can't design something to cater to my fantasy, you are no good.
    we're getting there....ESB's and all that rot that seem to have taken LEGO Mindstorms idea of drag and drop programming so that any idiot can make an application.
  • Nobody 2012-07-24 18:17
    rjb:
    Perhaps I misworded what I said. What I meant was compiles properly, and exhibits the desired behavior. If it doesn't exhibit the desired behavior, then I wouldn't say it compiled properly, it just compiled. :p
    Er...so did the OP's - or so it seemed. How do you know if it exhibits the desired behaviour? Just because something appears to work, does not mean it is working. In fact, if we play with memory the wrong way we'll often create errors that occur some of the time but not all of the time (because at each run the memory being used is different - sometimes it may be empty, other times not). Playing the "I just want it to compile" game can be very dangerous - even if you think you are verifying the behaviour.
  • a;skur 2012-07-24 18:20
    Steve The Cynic:
    java.lang.Chris;:
    Seeing that attempt at "string concatenation" leaves me with the feeling that Benedikt's predecessor may have been a Java programmer.

    As opposed to a colleague of mine at a previous job of mine, who had been doing too much work with JavaScript.

    So, to present a message like "Elements found: {number}", he would exploit JavaScript's unnatural fascination with automatic type conversions:
      var value = calculationFunction( parameters );
    
    var message = "Elements found: " + value;

    This doesn't work so well in C++.
    Ooh, I know, C++ doesn't use "var" ;)
  • johnno the wonderful 2012-07-24 18:26
    [quote user="Cbuttius"]Using the null character to denote end of string has its advantages but can be a WTF at times.

    Prefixing the length means it is faster to calculate the length of the string but makes it less maintainable. Firstly the potential length of the string is limited by the length of its header, and secondly when you modify the string you have to modify this length.

    In addition, there is the method of "tokenising" a string that into lots of strings by modifying the "separator" character into a null, allowing each component to be a string on its own. In fact sometimes you use a double zero to indicate the end of the sequence.

    Of course for binary "blobs" there will often be embedded null characters but in general these are not modified or lengthened the same way strings often are.

    The real WTF with C++ and strings is that the standard string is:
    1. really a typedef of template basic_string<char, char_traits<char>, allocator<char> >
    2. No standard ABI so if your library uses std::string in its interface it isn't guaranteed to work with a different library that uses a different compiler.

    It wasn't that long ago that you couldn't even pass a std::string between DLLs / shared objects built with the same compiler.

    All of which leads to you finding lots of "own implementations" of string, especially in legacy code.

    Of course, legacy code is still around because people still use these projects that are being maintained and they brought in enough money to the business.

    [/quote]


    [quote=lucidfox]
    TRWTF is rolling out their own string implementation.

    You know, as if C++ doesn't have enough of these already.
    [/quote]
    uhm.....
  • hear hear 2012-07-24 18:28
    Stev:
    TRWTF is people complaining that a language "lets you shoot yourself in the foot". A gun will let you shoot yourself in the foot, much like a hammer will let you smash your thumb and a saw will let you cut your fingers off. C++ is a tool like any other and will cause a bloody mess if used without proper training or care, or if used in an inappropriate situation.

    You wouldn't use a chainsaw to slice a lemon in a cramped kitchen, nor would you use a carving knife to cut down a tree. C++ is no different - it has its place and where it is used appropriately it is positively unmatched. Likewise, when used inappropriately it'll cause massive amounts of bloodshed.

    The same can be said for just about any language. Deal with it.
    ++
  • SOme dude 2012-07-24 18:36
    AGray:
    java.lang.Chris;:
    Sadly, there's a lot of odd code that a C++ compiler will happily compile:


    [chris@titwank ~]$ cat ouch.cpp
    #include <iostream>
    #include <string>

    using namespace std;

    int
    main()
    {
    string s = "Are we having fun yet?";
    int value = 0xdeadbeef;
    cout << s.c_str() + value << endl;
    return 0;
    }
    [chris@titwank ~]$ c++ -o ouch ouch.cpp
    [chris@titwank ~]$ ./ouch
    Segmentation fault (core dumped)



    I am TRWTF - I do not follow (exactly) what's happening here. I can see the bit where that hex offset is added to the output stream. I'm not sure how this causes a Segmentation fault...explanation please?
    s.c_str() is a character array, so it's essentially a pointer to a character (the beginning of the string) adding that hex value to that pointer likely puts the pointer outside the bounds of the knowable C universe and the output stream tries to display the data at an invalid adress
  • PiisAWheeL 2012-07-24 18:58
    rjb:
    Perhaps I misworded what I said. What I meant was compiles properly, and exhibits the desired behavior. If it doesn't exhibit the desired behavior, then I wouldn't say it compiled properly, it just compiled. :p
    I beg to differ.

    If it compiled, and it behaved the way the code was written, then it compiled correctly. If it does not exhibit the desired behavior, you have a logic problem, and that is your fault. It still compiled properly.

    Remember: the computer is a high speed idiot. It does exactly what you tell it to. Its your fault if your code doesn't exhibit the desired behavior, not the compilers.
  • Meep 2012-07-24 22:53
    Severity One:
    TRWTF is pointers.


    No, TRWTF is null-delimited, mutable strings. We still use them 30 years after they've proven to be a total security disaster. Because they're "simple."

    Every time a project manager says, "keep it simple, stupid", if you don't slap the shit out of him, God will make an earthquake kill a village full of orphans and puppies.
  • Mitch 2012-07-24 23:28
    Meep:
    Severity One:
    TRWTF is pointers.


    No, TRWTF is null-delimited, mutable strings. We still use them 30 years after they've proven to be a total security disaster. Because they're "simple."

    Every time a project manager says, "keep it simple, stupid", if you don't slap the shit out of him, God will make an earthquake kill a village full of orphans and puppies.
    Forget Strings. Just use space delimited words or full-stop (period) delimited sentences.

    50 characters should be enough to store a word (the scientists and medical researchers who think it's cool to use longer words can make longer words themselves).
    1000 character sentence limits should be reasonable too.

    The whole concept of a string is a bit like the whole concept of a number - and we had a pleasant conversation the other day about the whole concept of numbers....

    At the end of the day, we store DATA. Data is just arbitrary sequences of characters (expressed one way or another). Array's make perfect sense to store data, but the limits have to be controlled or tracked. It is fine to have a dynamically allocated array (in C terms memory that we might realloc) provided you always know how long it is (or at least the maximum length it's supposed to be). Nothing wrong with the string being mutable either - provided you do some checking on what is being mutated. Null delimiters, on the other hand, are a little silly because they force the exclusion of null in your data. That said, for many applications (like text processing) they work reasonably sufficiently.
  • pangalactic 2012-07-25 00:15
    So true - I only ever wrote my own string implementation once. It was for converting between char *, std::string, wchar_t *, std::wstring, ATL::CAtlString, ATL::CStringT<TCHAR, StrTraitMFC<TCHAR> > &, ATL::CStringT<TCHAR, StrTraitMFC_DLL<TCHAR> > &, ATL::CComBSTR, _bstr_t, _variant_t, and their const references.
  • Jim 2012-07-25 00:28
    lucidfox:
    TRWTF is rolling out their own string implementation.

    You know, as if C++ doesn't have enough of these already.
    Just a thought - why is there already so many string implementations?

    Perhaps it's because over time people realize that the ones available might not work well for their purpose....

    What other functionalities do languages (and perhaps more to the point people who build libraries for said languages) provide multiple variants on because noone really does them veyr well?
  • Zirias 2012-07-25 02:21
    Mason Wheeler:
    java.lang.Chris;:
    Of course, TRWTF is C++. It could have been an elegant and simple object oriented superset of C, but instead it's a glorious example of how not to design a programming language.


    Is it even possible to create an elegant and simple superset of something that it itself neither elegant nor simple?


    C IS elegant and simple if a language replacing machine code with something readable and structured, but still close to the machine, is what you want. Of course, you'll never want to create "enterprise" software in C :)

    Oh and -- as long as you know how to actually implement OO concepts yourself, C gives you everything you need: pointers, structs and typedefs. So that's just another option for OOP "on top of" C.
  • Steve The Cynic 2012-07-25 03:32
    Asdlarfgs:
    Steve The Cynic:

    So, to present a message like "Elements found: {number}", he would exploit JavaScript's unnatural fascination with automatic type conversions:
      var value = calculationFunction( parameters );
    
    var message = "Elements found: " + value;


    How... how is that "exploiting JavaScript's unnatural fascination with automatic type conversions"? That's just the natural way to do it in most dynamic languages.

    The fact that it is the natural way to do it doesn't make it a good idea. I think I'd be safe in saying that the easiest way to make bugs hard to find is for the language itself to silently work around their consequences.

    Arguably the correct response to string+number should be a compiler error, as there isn't a single natural obvious interpretation *in human terms*.

    Sure, in C and C++, given the implied type of "Elements found: " (array of 17 const chars in C++, const pointer to const char in C, IIRCWIPD), the crash-inducing interpretation that he stumbled across is correct, if not entirely reasonable. And sure, in JavaScript, the interpretation of string+number as "convert the thing on the right to a string and construct a new string which is the left one with the right one concatenated to it" is also correct, but given the length of the description, perhaps equally unreasonable.

    So, we have two correct but deeply incompatible concepts of what to do with this particular construct, so I'd say that, as a context-free generalisation, neither of them is correct.

    Python, also a dynamic language, has the right idea: (2.7.2, YMMV on other versions)

    >>> "abc" + 5
    Traceback (most recent call last):
    File "<stdin>", line 1, in <module>
    TypeError: cannot concatenate 'str' and 'int' objects
  • Captain Fairly Understandable 2012-07-25 04:54
    Zylon:
    pitchingchris:
    I disagree. There are plenty of useful things you can do with operater overloading.

    But is there anything you can do with operator overloading that you can't do without it?

    No...

    Y'know, other than making your code harder to decipher for maintenance programmers? Operator overloading always seemed like self-indulgent syntactic sugar to me.

    The key is making the class self-documenting enough that it's obvious what overloaded operators do.

    The pay-off of operator overloads vs. methods is shorter code, which is in itself an aid to readability if built on good foundations. E.g.
    myStr + str2 + str3 + str4

    vs
    MyStr.append(str2).append(str3).append(str4)

    .
  • dkf 2012-07-25 05:05
    Cbuttius:
    Calling a pointer a reference doesn't mean it is not a pointer.
    No. There are a few key differences. References maintain some ownership of the referenced item, pointers don't. You can do certain types of arithmetic on a pointer (i.e., there's limited interconversion with integers) but references don't support any of that. While yes, pointers are part of the obvious way you'd implement references, there are distinct differences that make references simultaneously quite a bit less powerful and much safer, a good trade-off in a lot of situations.

    C++'s references are a particularly moronic way of doing references, which is why it's hard to think of another language that does them that way. By contrast, vast numbers of languages use references. (Heck, I suspect they're in Lisp and that predates C by 14 years.)
  • Severity One 2012-07-25 05:11
    Stev:
    You wouldn't use a chainsaw to slice a lemon in a cramped kitchen, nor would you use a carving knife to cut down a tree. C++ is no different - it has its place and where it is used appropriately it is positively unmatched. Likewise, when used inappropriately it'll cause massive amounts of bloodshed.
    The thing is, though, that C++ has a pretty small niche where it truly shines. In my opinion, this is mostly caused by (a) the syntax and (b) the lack of a standardised set of libraries until much later. And because there are plenty of situations where the lowered performance is acceptable as a trade-off for greater stability (meaning that it's more difficult to shoot yourself in the foot).
  • Cbuttius 2012-07-25 05:21
    pangalactic:
    So true - I only ever wrote my own string implementation once. It was for converting between char *, std::string, wchar_t *, std::wstring, ATL::CAtlString, ATL::CStringT<TCHAR, StrTraitMFC<TCHAR> > &, ATL::CStringT<TCHAR, StrTraitMFC_DLL<TCHAR> > &, ATL::CComBSTR, _bstr_t, _variant_t, and their const references.


    You missed vector<char> and vector<wchar_t>

  • gallier2 2012-07-25 05:35
    D, really. Unfortunately not widespread enough to be really used in production but still the best successor to C yet.
  • Cbuttius 2012-07-25 05:38
    danbruc:
    Cbuttius:
    Calling a pointer a reference doesn't mean it is not a pointer.
    That's not true. In C# there is a single thing you can do with a reference - dereference it. A reference is either a null reference or a reference to an object of its specific type. You are neither allowed to use pointer math to point to the interior of an object or to random garbage in memory, nor are you allowed to cast a reference to an arbitrary type without generating at least an invalid cast exception at runtime (unless the cast is valid of course).


    The primary difference appears to be that if you perform an illegal pointer operation that in C++ produces "undefined behaviour" and in C# produces a runtime exception, it's easier to recover or debug in C#.

    Either way it's still a bug. And either way, your code compiles then fails at runtime. The ideal solution for a bug is a compile-time error so that it never gets released.

    In C++ a pointer can "double up" as an iterator in a contiguous memory buffer thus allowing you to perform arithmetic on it. This is inherited from C and being "closer to the hardware". In managed languages there is no concept of a "contiguous buffer" as you don't care how the data is actually stored in memory, it is just a concept of a storage of multiple data objects. So you have to use the language iterators to move between them.

    In C++, it is exactly this optimisation that allows you to handle large collections more efficiently.

    Some of the real WTFs in C++ as a language are not being mentioned here. These include:

    - having to define virtual destructor into base classes to make them delete properly.

    - delete and delete[]. Ideally the compiler should just know.

    - iostream: rather horrific

    in addition to the lack of a standard for libraries (DLLs, shared objects, etc) as well as loads of other stuff that should ideally be in a standard library but is not.
  • Cbuttius 2012-07-25 05:39
    gallier2:
    D, really. Unfortunately not widespread enough to be really used in production but still the best successor to C yet.


    Because it needs a huge library base which it doesn't have.
  • Zirias 2012-07-25 08:05
    Cbuttius:
    danbruc:
    Cbuttius:
    Calling a pointer a reference doesn't mean it is not a pointer.
    That's not true. In C# there is a single thing you can do with a reference - dereference it. A reference is either a null reference or a reference to an object of its specific type. You are neither allowed to use pointer math to point to the interior of an object or to random garbage in memory, nor are you allowed to cast a reference to an arbitrary type without generating at least an invalid cast exception at runtime (unless the cast is valid of course).

    The primary difference appears to be that if you perform an illegal pointer operation that in C++ produces "undefined behaviour" and in C# produces a runtime exception, it's easier to recover or debug in C#.

    Although this is technically correct, you DO realize the only "illegal pointer operation" possible on a C# reference IS dereferencing the null reference? As opposed to all the dangling pointer issues imaginable in C/C++?

    That's what makes a reference a reference. It's the same when it comes to implementation on the (virtual or physical) machine -- but in terms of the language, it's something completely different. You can manipulate a pointer as you wish, you cannot manipulate a reference -> less powerful, more secure.

    C# knows pointers as well, but clearly separates them from references (cannot refer a C# object using a C# pointer) and only allows them in a discouraged "unsafe" context.

    TRWTF is C++ using both concepts at the same time and interchangeably
  • Cbuttius 2012-07-25 08:17
    Mitch:
    Meep:
    Severity One:
    TRWTF is pointers.


    No, TRWTF is null-delimited, mutable strings. We still use them 30 years after they've proven to be a total security disaster. Because they're "simple."

    Every time a project manager says, "keep it simple, stupid", if you don't slap the shit out of him, God will make an earthquake kill a village full of orphans and puppies.
    Forget Strings. Just use space delimited words or full-stop (period) delimited sentences.

    50 characters should be enough to store a word (the scientists and medical researchers who think it's cool to use longer words can make longer words themselves).
    1000 character sentence limits should be reasonable too.

    The whole concept of a string is a bit like the whole concept of a number - and we had a pleasant conversation the other day about the whole concept of numbers....

    At the end of the day, we store DATA. Data is just arbitrary sequences of characters (expressed one way or another). Array's make perfect sense to store data, but the limits have to be controlled or tracked. It is fine to have a dynamically allocated array (in C terms memory that we might realloc) provided you always know how long it is (or at least the maximum length it's supposed to be). Nothing wrong with the string being mutable either - provided you do some checking on what is being mutated. Null delimiters, on the other hand, are a little silly because they force the exclusion of null in your data. That said, for many applications (like text processing) they work reasonably sufficiently.


    It is somewhat interesting that strings are considered unlimited but numbers are limited to a certain number of bits and you need lots of different versions to be able to deal with that and there isn't even an unlimited version for when you need one.

    Also still a WTF in C++ that numbers are not standardly portable.

    The lack of an immutable reference-copied string class is a shortcoming in the C++ library. A lot of the time you want a "create in one place then pass around a lot" string. It is fairly trivial to write one too, and should ideally "copy by value" short strings (using a local buffer).

    Then you have all the issues with unsigned char, char and signed char when in reality you probably want char to be unsigned most of the time unless you want to handle "tiny" ints that might be negative. I don't recall ever having such a situation (where I couldn't use int instead). In this case you can then use the same data structure for binary blobs as you would use for textual strings, i.e. they are just a collection of bytes.

    Binary representation of structured data, i.e. marshalling and unmarshalling for sending across networks, storing in files etc. is badly supported by the C++ standard libraries.
    iostream even "fools" you by allowing you to set a "binary" mode. I remember when I was a naive beginner and after setting the stream to binary, didn't understand why my numbers were still printing as text....

    I think I stuck with FILE* functions long into my C++-writing career, whereas others seem to write all their code in C except for iostream, something I never understand. Why use C++ only for its weakest feature?



  • Sten 2012-07-25 08:19
    TRWTF is stupid developer using pointers. Seriously, there should be C++ switch that would allow using raw pointers only to experienced developers because they know that they should not use them unless absolutely necessary and even then they should be very very very careful.
  • Nagesh 2012-07-25 08:48
    That's brillant!
  • Anonandon 2012-07-25 09:06
    Cbuttius:

    <snip>

    Some of the real WTFs in C++ as a language are not being mentioned here. These include:

    - having to define virtual destructor into base classes to make them delete properly.

    - delete and delete[]. Ideally the compiler should just know.

    - iostream: rather horrific

    in addition to the lack of a standard for libraries (DLLs, shared objects, etc) as well as loads of other stuff that should ideally be in a standard library but is not.

    I was about to say "all protected/public methods not being virtual by default", but would this force the compiler to create inheritance infrastructure that you knew was never going to be used?
  • Anonandon 2012-07-25 09:13
    Sten:
    TRWTF is stupid developer using pointers. Seriously, there should be C++ switch that would allow using raw pointers only to experienced developers because they know that they should not use them unless absolutely necessary and even then they should be very very very careful.


    I guess there'd have to be an exception for header files included by your source, since any of these might have raw pointers in its declarations, and at worst might even include code that allocated or released memory?
  • Fell 2012-07-25 09:35
    Severity One:
    TRWTF is pointers.


    -- Umm yeah... because memory's really useful without ADDRESSES
  • Cbuttius 2012-07-25 10:00
    Anonandon:

    I was about to say "all protected/public methods not being virtual by default", but would this force the compiler to create inheritance infrastructure that you knew was never going to be used?


    You can have private virtual methods and they make sense. Many developers like a pattern of having public non-virtual methods calling private virtual ones. Sometimes protected virtual works better here so that one implementation can call its base-class implementation in addition to adding to it.

    If it wre possible to extend the language, you could allow "interface" as well as "class" and "struct" and when a class is declared with "interface" all methods are virtual by default. Maybe even pure virtual. An interface would not have a user-defined constructor, would automatically have a virtual destructor and would not be copyable (other than with possible clone() function) or assignable.

    There would be no need to create a compilation unit to house its v-table (i.e. its virtual destructor implementation that is empty) because all compilers would view it exactly the same (there would be standard v-table implementation).

    This is not essential though. We can manage without it. It doesn't add anything new to the language you can't already do if you are skilled in it. Yes, virtual void whatever() = 0; looks messy but it works and there are more important issues to address in my opinion.

    If I were writing a new language or redesigning one or whatever, I would keep the concept of "headers" to show the interface of a class and keep it separated from its implementation. I would however change the way it currently works in C++ where a header file is simply code that gets added to the source of the compilation unit. Instead a header would be a fully-blown class and function definition file that would get compiled separately and what is defined there would be added to some kind of "database". Then your compilation units would be compiled on top of that. Of course it would get tricky when it comes to templates (or generics), meta-programming, type-traits and partial specialization. type traits would probably become a language feature so when a class/type is defined, you would also define what traits it has.


  • ¯\(°_o)/¯ I DUNNO LOL 2012-07-25 10:09
    Zirias:
    Oh and -- as long as you know how to actually implement OO concepts yourself, C gives you everything you need: pointers, structs and typedefs. So that's just another option for OOP "on top of" C.
    I've done it before with function pointers. But C's pointer-to-function syntax is its own whole can of WTF.

    Cbuttius:
    - iostream: rather horrific
    I am still firmly convinced that the whole point of the iostream library was "Hey lookie here, I can overload the left shift and right shift operators to do I/O thingies!" (And now I have a vision of Cletus from The Simpsons saying that.)

    So how come when people defend operator overloading, it's always "BUT MAAAAATRIX MATH!" Because so many people need to do matrix math.

    Cbuttius:
    Then you have all the issues with unsigned char, char and signed char when in reality you probably want char to be unsigned most of the time unless you want to handle "tiny" ints that might be negative. I don't recall ever having such a situation (where I couldn't use int instead).
    It's so much fun when I'm trying to display bytes as hex using %02X format and I get FFFFFFC9, etc. in the output. Sure, some compilers let you set char to default as unsigned, but how you specify that is basically non-portable.

    Cbuttius:
    I think I stuck with FILE* functions long into my C++-writing career, whereas others seem to write all their code in C except for iostream, something I never understand. Why use C++ only for its weakest feature?
    Because it holds your hand. (Except when you forget and leave the stream in hex or some strange formatting mode. Then it abandons you in the desert.) And printf format specifiers are haaaaaaaard.

    That's the one feature of C++ that I absolutely refuse to use. It wasn't needed, and it's just a stunt trick to justify operator overloading abuse.
  • Severity One 2012-07-25 11:01
    Cbuttius:
    You can have private virtual methods and they make sense. Many developers like a pattern of having public non-virtual methods calling private virtual ones. Sometimes protected virtual works better here so that one implementation can call its base-class implementation in addition to adding to it.
    Isn't "private" meant to imply that it's, well, private? In Java, you can't have private abstract methods, partly because it's discouraged to invoke anything that could be overridden from the constructor.

    Cbuttius:
    If it wre possible to extend the language, you could allow "interface" as well as "class" and "struct" and when a class is declared with "interface" all methods are virtual by default. Maybe even pure virtual. An interface would not have a user-defined constructor, would automatically have a virtual destructor and would not be copyable (other than with possible clone() function) or assignable.

    There would be no need to create a compilation unit to house its v-table (i.e. its virtual destructor implementation that is empty) because all compilers would view it exactly the same (there would be standard v-table implementation).

    This is not essential though. We can manage without it. It doesn't add anything new to the language you can't already do if you are skilled in it. Yes, virtual void whatever() = 0; looks messy but it works and there are more important issues to address in my opinion.

    If I were writing a new language or redesigning one or whatever, I would keep the concept of "headers" to show the interface of a class and keep it separated from its implementation. I would however change the way it currently works in C++ where a header file is simply code that gets added to the source of the compilation unit. Instead a header would be a fully-blown class and function definition file that would get compiled separately and what is defined there would be added to some kind of "database". Then your compilation units would be compiled on top of that. Of course it would get tricky when it comes to templates (or generics), meta-programming, type-traits and partial specialization. type traits would probably become a language feature so when a class/type is defined, you would also define what traits it has.
    So basically, you've described Java.
  • Asdlarfgs 2012-07-25 11:45
    Zylon:
    pitchingchris:
    I disagree. There are plenty of useful things you can do with operater overloading.

    But is there anything you can do with operator overloading that you can't do without it? Y'know, other than making your code harder to decipher for maintenance programmers? Operator overloading always seemed like self-indulgent syntactic sugar to me.

    Fucking no.
    As they said:
    Captain Fairly Understandable:
    myStr + str2 + str3 + str4

    vs
    MyStr.append(str2).append(str3).append(str4)

    .


    History Teacher:

    Do not underestimate syntactic sugar.


    There is something I think people tend to forget. EVERY DETAIL IS IMPORTANT. Yes, of course you can do everything without operator overloading. You can also do everything in assembly. Do you program in assembly? Or Turing machines. Those little conveniences are the whole reason to use a language, and the whole reason people derail threads every day to bash or defend some language. (Portability? No, assembly is portable too. You just have to write a program that translates it to another

    Of course, you could argue that the inconvenience of not knowing if an operator is calling a function or not is worse than the convenience of operator overloading. Arguably there could be ways to mitigate this. Or the inconvenience of having to implement it, which makes you have less tools available. But "you don't technically need it" is never a good argument.
  • Mike 2012-07-25 12:10
    Typeless languages scare the heck out of me... then again so do languages that make type conversion too easy...
  • senior moron 2012-07-25 13:12
    TRWTF is all you arrogant bastages think you know best. I've never seen such a bunch of knuckleheads so full of themselves.
  • Prosthetic Lips 2012-07-25 21:55
    Jack:
    Dave-Sir:
    However, because of precedence rules
    Precedence? WTF is precedence? That looks like a Very Big Word. I should not have to know it. I should not have to know anything. The computer should just do what I want.

    Programming languages are TRWTF. Nobody wants to type commands. So boring. And hard, dammit! There should just be a big round candy colored button and when I click it, it reads my mind and Just Works. If you can't design something to cater to my fantasy, you are no good.


    Ah, a Mac guy. At first I thought, "troll," then I caught on from the use of, "candy colored." You know, like the cute little iMacs that no one uses any more.
  • sdlkfh 2012-07-25 21:58
    senior moron:
    TRWTF is all you arrogant bastages think you know best. I've never seen such a bunch of knuckleheads so full of themselves.
    With a hint of irony, I present......"senior moron" *clapping*
  • Imogen 2012-07-25 21:59
    Severity One:
    Stev:
    You wouldn't use a chainsaw to slice a lemon in a cramped kitchen, nor would you use a carving knife to cut down a tree. C++ is no different - it has its place and where it is used appropriately it is positively unmatched. Likewise, when used inappropriately it'll cause massive amounts of bloodshed.
    The thing is, though, that C++ has a pretty small niche where it truly shines. In my opinion, this is mostly caused by (a) the syntax and (b) the lack of a standardised set of libraries until much later. And because there are plenty of situations where the lowered performance is acceptable as a trade-off for greater stability (meaning that it's more difficult to shoot yourself in the foot).
    Horses for Courses. There are situations I'd consider using C++ and situations I wouldn't.

    Similarly, there are situations I'd consider using Java/C#/<ruby/LISP/Miranda/Prolog/<insert any language here> and situations I wouldn't.

  • Bill 2012-07-25 22:10
    It frightens me a little that there's so much language-bashing here.
    A bad tradesman always blames his tools. Sure some languages are easier to use than other, some better suited to some task or the other, but the question of what is better depends on the purpose and, to a degree, the user.
    Higher level languages are often used to create business applications - because there's a perception that they are more idiot-proof and allow reasonable complexity to be programmed fairly quickly, even with inexperienced developers. Lower level languages tend to have a reputation for tasks that a closer to the hardware (such as drivers and embedded systems {even with no file system}) and are also used for tasks that need to flog the processor (scientific calculation might be one example).

    Take a look around the world at off-the-shelf software you buy, and see if you can work out what languages are most common in the 'home user' environment.
  • Zirias 2012-07-26 01:46
    Bill:
    A bad tradesman always blames his tools.

    And we all know tradesmen cannot handle tools anyway ...
  • Severity One 2012-07-26 03:12
    Bill:
    It frightens me a little that there's so much language-bashing here.
    Only C++ bashing from me, but that's my pet hate. I like C, I like Java, but C++ is an abomination (in my opinion, of course).

    Bill:
    A bad tradesman always blames his tools.
    You may want to rephrase that. :)

    Bill:
    Sure some languages are easier to use than other, some better suited to some task or the other, but the question of what is better depends on the purpose and, to a degree, the user.
    Higher level languages are often used to create business applications - because there's a perception that they are more idiot-proof and allow reasonable complexity to be programmed fairly quickly, even with inexperienced developers. Lower level languages tend to have a reputation for tasks that a closer to the hardware (such as drivers and embedded systems {even with no file system}) and are also used for tasks that need to flog the processor (scientific calculation might be one example).
    Sure, but you go and try to exploit a buffer overrun in Java.

    I still see the occasional security advisory which would allow some exploit, sometimes even a remote root exploit. And invariably, this has to do improper handling of byte arrays.

    So even though most system software is written in C (or C++), it wouldn't hurt (except performance) if this became some managed version of C. Not all the way to the virtualisation that Java offers, but some extra checks, particularly boundary checks.
  • foxyshadis 2012-07-26 04:23
    Mike:
    Typeless languages scare the heck out of me... then again so do languages that make type conversion too easy...


    In that case, I would assume that inheritance and void pointers scare you too. Every language has some way around static typing.

    In languages with true dynamic typing, the one and only legitimate use of it is when you can get various types into a single variable and want to coerce them all into one type, without being too limited in what you'll initially accept. All other uses are laziness in my experience. The more common scenario, where one variable has one type for its entire lifetime, is extremely useful whether or not that type is declared or made implicit. Same benefits either way, which is why C# got the 'var' keyword.
  • Cbuttius 2012-07-26 05:39
    Severity One:
    Cbuttius:
    You can have private virtual methods and they make sense. Many developers like a pattern of having public non-virtual methods calling private virtual ones. Sometimes protected virtual works better here so that one implementation can call its base-class implementation in addition to adding to it.
    Isn't "private" meant to imply that it's, well, private? In Java, you can't have private abstract methods, partly because it's discouraged to invoke anything that could be overridden from the constructor.

    Not exactly, private means the access is restricted only to the class in which it is defined and its friends. It doesn't mean you are not supposed to know it exists. At first programmers did find it difficult to comprehend though, so much so that the "official" C++ faq (the one at parashift.com) advised programmers to use protected. I usually prefer protected for the reason I described earlier.

    Cbuttius:
    If it wre possible to extend the language, you could allow "interface" as well as "class" and "struct" and when a class is declared with "interface" all methods are virtual by default. Maybe even pure virtual. An interface would not have a user-defined constructor, would automatically have a virtual destructor and would not be copyable (other than with possible clone() function) or assignable.

    There would be no need to create a compilation unit to house its v-table (i.e. its virtual destructor implementation that is empty) because all compilers would view it exactly the same (there would be standard v-table implementation).

    This is not essential though. We can manage without it. It doesn't add anything new to the language you can't already do if you are skilled in it. Yes, virtual void whatever() = 0; looks messy but it works and there are more important issues to address in my opinion.

    If I were writing a new language or redesigning one or whatever, I would keep the concept of "headers" to show the interface of a class and keep it separated from its implementation. I would however change the way it currently works in C++ where a header file is simply code that gets added to the source of the compilation unit. Instead a header would be a fully-blown class and function definition file that would get compiled separately and what is defined there would be added to some kind of "database". Then your compilation units would be compiled on top of that. Of course it would get tricky when it comes to templates (or generics), meta-programming, type-traits and partial specialization. type traits would probably become a language feature so when a class/type is defined, you would also define what traits it has.
    So basically, you've described Java.


    No, in Java you cannot define a class header and put the implementation elsewhere. I cannot look at a header for a class to see what its methods are.

    A good extension of C++ would be to allow this:

    class Derived : public Base;


    as a partial forward declaration. I don't think that's even allowed in C++11.

    Another thing that should be allowed is:


    typename std::string;


    or

    namespace std { typename string; }

    You cannot do

    namespace std { class string; }

    because string is not actually a class, it is a typedef (alias) for basic_string<char, char_traits<char>, allocator<char>

    Of course if we got rid of headers the way they are you would simply put in

    using std::string;


    and that would automatically allow you to use std::string in your project with all its methods. Headers would be used to create your own classes and functions.
  • Cbuttius 2012-07-26 10:06
    [quote user="Cbuttius"]- iostream: rather horrific[/quote]I am still firmly convinced that the whole point of the iostream library was "Hey lookie here, I can overload the left shift and right shift operators to do I/O thingies!" (And now I have a vision of Cletus from The Simpsons saying that.)
    ...

    That's the one feature of C++ that I absolutely refuse to use. It wasn't needed, and it's just a stunt trick to justify operator overloading abuse.[/quote]

    ostringstream is the best option the library provides as a string builder.

    The iomanip feature is all wrong... If I want to print a char in "%02x" format I want to do just that... not change the stream so that everything I output will be formatted that way from now on until I change it back.

    You can't conveniently use istream >> operator to read back what you wrote in the same way that you wrote it because it has no way of knowing where tokens end.

    Output the numbers 1, 2, 3 in that order and read back and it will read 123 then not find any more numbers. Output a string "Hello world" and it will read back only "Hello" as it thinks the space denotes the end of the string.

    In any case it is flawed that istream >> should be used to write into "objects". In reality you load into factories and then use those factories to create objects. Yes, I know the factories are also objects, but you write directly from the objects but read back into the factories.

    I am not sure how other languages handle this any better.

    Of course, there is more than one way to represent an object in persistent format and you should be able to decouple these whilst ensuring your model is extensible in both directions. (Where visitor pattern in its classic form fails but works with adapter pattern clipped on).

  • null 2012-07-26 11:03
    Severity One:
    History Teacher:
    Severity One:
    TRWTF is pointers.

    ...are you the author of this particular representative line, by any chance?
    No.

    History Teacher:
    TRWTF are coders who don't understand pointers, yet touch any language less separated from hardware than crossplatform HTML+javascript.
    Oh, I understand pointers, but they are too easy to muck up, especially with C++'s Byzantine syntax, and an object-oriented language offers enough tools to pretend that pointers do not exist (such as Java does). Unless you're doing serious low-level or high-performance computing, there isn't much use for pointers.


    Ever heard of linked lists, passing a variable 'by reference', etc.?
  • Otherwise also known as ... 2012-07-26 11:42
    Cbuttius:
    Severity One:

    So basically, you've described Java.

    No, in Java you cannot define a class header and put the implementation elsewhere.

    Surely you can. However the class header in the Java world is named "interface".

    CAPTCHA: usitas - Take the interface and usitas class header.
  • no laughing matter 2012-07-26 11:49
    null:
    Severity One:

    Oh, I understand pointers, but they are too easy to muck up, especially with C++'s Byzantine syntax, and an object-oriented language offers enough tools to pretend that pointers do not exist (such as Java does). Unless you're doing serious low-level or high-performance computing, there isn't much use for pointers.


    Ever heard of linked lists, passing a variable 'by reference', etc.?

    Neither of these use cases require pointers with the properties of C++-pointers: Allowing to point anywhere, allowing to dereference after pointed object ia already freed, allowing to point to null, support of pointer-arithmetics.
  • jMerliN 2012-07-26 14:21
    Asdlarfgs:

    There is something I think people tend to forget. EVERY DETAIL IS IMPORTANT. Yes, of course you can do everything without operator overloading. You can also do everything in assembly. Do you program in assembly? Or Turing machines. Those little conveniences are the whole reason to use a language, and the whole reason people derail threads every day to bash or defend some language. (Portability? No, assembly is portable too. You just have to write a program that translates it to another

    Of course, you could argue that the inconvenience of not knowing if an operator is calling a function or not is worse than the convenience of operator overloading. Arguably there could be ways to mitigate this. Or the inconvenience of having to implement it, which makes you have less tools available. But "you don't technically need it" is never a good argument.


    You've literally just provided an argument and an argument against your argument at the same time. We understand the point of syntactic sugar. Nobody is going to argue with that. It's a valuable thing that makes our lives easier. But in the end, syntax is in the realm of language design. When you allow people to define the the operator implementations in the language, you're effectively handing them the ability to write their own language.

    There's a huge difference between not using any syntactic sugar (ie, not using any higher level languages) and being able to define your own language by overloading syntax features. C++ isn't a replacement for yacc/bison, so we shouldn't treat it as such. I don't care that you saved 7 characters by using a + instead of a .add, the latter is infinitely more clean and understandable by anyone. I don't have to second guess myself when reading your code at every point whether an operator is overloaded. And when using your code, I don't have to think should I call a function or does this object support an operator. When you want to invoke a custom operation on things, you call a function. This is convention. It's a good thing. It's a good thing for the same reason syntactic sugar is a good thing: it provides consistency to a set of operations, except in this case it's more meta regarding the language and how we use it, not regarding specific objects in some application, so hierarchically speaking, it's more important than sugar. And in the end, that's all syntax features in a language do for us: provide consistency. Operator overloading fundamentally breaks that consistency. To throw away good conventions to invent your own nonstandard sugar is TRWTF.
  • Severity One 2012-07-27 03:21
    null:
    Severity One:
    Oh, I understand pointers, but they are too easy to muck up, especially with C++'s Byzantine syntax, and an object-oriented language offers enough tools to pretend that pointers do not exist (such as Java does). Unless you're doing serious low-level or high-performance computing, there isn't much use for pointers.
    Ever heard of linked lists, passing a variable 'by reference', etc.?
    For clarity's sake, I've highlighted the essential part.
  • Cbuttius 2012-07-27 04:25
    C++ has to allow pointer arithmetic because it is a feature of C, and C++ inherits all the features of C. It is not a complete superset in that

    C++ allows "dangling" pointers to exist for the same reason. Plus the fact it is not garbage collected so you call "delete" (or free which still works) when you decide you no longer need the object / memory. If there are still pointers pointing to it, the compiler still does what you ask it to.

    1. some of the type checking is stricter in C++
    2. C++ introduces new keywords that are not present in C so C code that uses these won't compile in C++ (eg. "new", "delete", "class")

    Java and C# are easier to debug because when you have a runtime error, it checks for you. But these continual checks also make your code slower when there are no bugs. In C++ you usually have the option of a debug build, where the checks are made, and the release build where they are not.

    I do agree that exceptions are badly implemented in C++. But I think they are in C# and Java too. Using the type system for catching is a bad way of doing it. There should be a single exception class that has just a buffer of small header and a buffer of data. The header will tell you what kind of exception you have and the data section will give more detail. It should be a compiler option whether or not to include a call-stack in the exception.

    C++ is often used to build DLLs / shared objects rather than applications and will often expose a C interface. But by writing the application in C++ you can take advantage of using STL for collections, shared_ptr and RAII for better resource and memory management, polymorphism and other positive features that makes C++ a easier language to write.

    These shared objects are not only used for C programs. They are used for any language with C bindings, including many scripting languages.

    This is C++ domain. So are the scripting language interpreters. So is writing these libraries that this "domain" can take advantage of.


  • Severity One 2012-07-27 05:56
    Cbuttius:
    Java and C# are easier to debug because when you have a runtime error, it checks for you. But these continual checks also make your code slower when there are no bugs. In C++ you usually have the option of a debug build, where the checks are made, and the release build where they are not.
    There are always bugs. If you don't know of any bugs, you just haven't found all of them.

    But let's have a look at the following Java code:

    int[] array = new int[10];
    
    for( int index = 0; index < array.length; index++ )
    {
    array[index] = index;
    }

    In this case, you don't need a boundary check, because (a) the array is never re-assigned and (b) the index variable isn't modified outside the 'for' statement. Now whether the just-in-time compiler takes advantage of this is another issue, but the complaint against boundary checks doesn't always hold.

    Cbuttius:
    I do agree that exceptions are badly implemented in C++. But I think they are in C# and Java too. Using the type system for catching is a bad way of doing it. There should be a single exception class that has just a buffer of small header and a buffer of data. The header will tell you what kind of exception you have and the data section will give more detail. It should be a compiler option whether or not to include a call-stack in the exception.
    So instead of having multiple catch statements, and being able to take advantage of inheritance, you suggest that we should throw a switch statement at the exception header? That doesn't make any sense. Perhaps the exception system in Java and C# could be improved, but not in the way you describe it.

    And what are you going to do if your application crashes, and you don't have a stack trace because you thought it necessary to speed up exception handling? That doesn't make any sense.

    So much time in computer programs is wasted on either disc, databases, network resources or user input, that it doesn't make sense to try and optimise everything, unless you're doing serious high-performance computing. But then you're in a completely different ballpark.
  • Cbuttius 2012-07-27 07:44
    [quote user="Severity One[quote user="Cbuttius"]I do agree that exceptions are badly implemented in C++. But I think they are in C# and Java too. Using the type system for catching is a bad way of doing it. There should be a single exception class that has just a buffer of small header and a buffer of data. The header will tell you what kind of exception you have and the data section will give more detail. It should be a compiler option whether or not to include a call-stack in the exception.[/quote]

    So instead of having multiple catch statements, and being able to take advantage of inheritance, you suggest that we should throw a switch statement at the exception header? That doesn't make any sense. Perhaps the exception system in Java and C# could be improved, but not in the way you describe it.

    And what are you going to do if your application crashes, and you don't have a stack trace because you thought it necessary to speed up exception handling? That doesn't make any sense.

    So much time in computer programs is wasted on either disc, databases, network resources or user input, that it doesn't make sense to try and optimise everything, unless you're doing serious high-performance computing. But then you're in a completely different ballpark.[/quote]

    1. On using "switch" to find out the cause, essentially yes, albeit it doesn't have to be a switch statement, it could be an exception handling routine or factory or whatever. 99.9% of the time though I do a try..catch I don't put in multiple handlers. You tried something, it failed and you report back to the user why the operation did not work. Too often, exceptions are thrown from the "pImpl" using exception classes created by the pImpl and the whole point is to encapsulate the pImpl out so the user doesn't know the implementation. At user call level you want to know if it passed or failed and stop the execution immediately on failure. Java code is full of try..catch everywhere. In C++ you are more likely to let exceptions fall through to where they will be finally caught and handled, and there is no need for finally in C++ because you have destructors.

    2. Exceptions are often not used on embedded systems exactly because they are too heavy. The ability to have a lighter exceptions system would get around this drawback. You always assume that every program runs on a big system with lots of resources. In such a case, a call stack could well be far too heavy and needs to be optional.

  • null 2012-07-27 10:12
    no laughing matter:
    null:
    Severity One:

    Oh, I understand pointers, but they are too easy to muck up, especially with C++'s Byzantine syntax, and an object-oriented language offers enough tools to pretend that pointers do not exist (such as Java does). Unless you're doing serious low-level or high-performance computing, there isn't much use for pointers.


    Ever heard of linked lists, passing a variable 'by reference', etc.?

    Neither of these use cases require pointers with the properties of C++-pointers: Allowing to point anywhere, allowing to dereference after pointed object ia already freed, allowing to point to null, support of pointer-arithmetics.


    what does the last item in a linked list point to. Does it not point to null?
  • M 2012-07-27 11:34
    jMerliN:
    Asdlarfgs:

    There is something I think people tend to forget. EVERY DETAIL IS IMPORTANT. Yes, of course you can do everything without operator overloading. You can also do everything in assembly. Do you program in assembly? Or Turing machines. Those little conveniences are the whole reason to use a language, and the whole reason people derail threads every day to bash or defend some language. (Portability? No, assembly is portable too. You just have to write a program that translates it to another

    Of course, you could argue that the inconvenience of not knowing if an operator is calling a function or not is worse than the convenience of operator overloading. Arguably there could be ways to mitigate this. Or the inconvenience of having to implement it, which makes you have less tools available. But "you don't technically need it" is never a good argument.


    You've literally just provided an argument and an argument against your argument at the same time. We understand the point of syntactic sugar. Nobody is going to argue with that. It's a valuable thing that makes our lives easier. But in the end, syntax is in the realm of language design. When you allow people to define the the operator implementations in the language, you're effectively handing them the ability to write their own language.

    There's a huge difference between not using any syntactic sugar (ie, not using any higher level languages) and being able to define your own language by overloading syntax features. C++ isn't a replacement for yacc/bison, so we shouldn't treat it as such. I don't care that you saved 7 characters by using a + instead of a .add, the latter is infinitely more clean and understandable by anyone. I don't have to second guess myself when reading your code at every point whether an operator is overloaded. And when using your code, I don't have to think should I call a function or does this object support an operator. When you want to invoke a custom operation on things, you call a function. This is convention. It's a good thing. It's a good thing for the same reason syntactic sugar is a good thing: it provides consistency to a set of operations, except in this case it's more meta regarding the language and how we use it, not regarding specific objects in some application, so hierarchically speaking, it's more important than sugar. And in the end, that's all syntax features in a language do for us: provide consistency. Operator overloading fundamentally breaks that consistency. To throw away good conventions to invent your own nonstandard sugar is TRWTF.


    I completely disagree. Operator overloading has its place. It's use in C# string concatenation is an example. I much prefer:

    myString = string1 + string2 + string3
    over
    myString = string1.Add(string2).Add(string3)

    It should be obvious when a class needs operator support, both to the creator and to its users. Blaming the feature because idiots misuse it is silly. If we removed every language feature that people abuse, we'd all be writing assembly.
  • no laughing matter 2012-07-27 13:11
    null:
    no laughing matter:
    null:

    Ever heard of linked lists, passing a variable 'by reference', etc.?

    Neither of these use cases require pointers with the properties of C++-pointers: Allowing to point anywhere, allowing to dereference after pointed object ia already freed, allowing to point to null, support of pointer-arithmetics.


    what does the last item in a linked list point to. Does it not point to null?

    Of course not!

    It points to the single instance of the Null-Object!
  • jMerliN 2012-07-27 14:02
    M:

    I completely disagree. Operator overloading has its place. It's use in C# string concatenation is an example. I much prefer:

    myString = string1 + string2 + string3
    over
    myString = string1.Add(string2).Add(string3)

    It should be obvious when a class needs operator support, both to the creator and to its users. Blaming the feature because idiots misuse it is silly. If we removed every language feature that people abuse, we'd all be writing assembly.


    It's not about idiots and it's not about actual misuse. It's about the fact that it brings uncertainty into a language. For instance, both of your examples are bad. I can't tell immediately whether those are actually strings you're working with because "+" is very generic and so is "Add". I can't tell if you're mutating objects or using immutables. The "+" operator in most languages and in Mathematics does not modify its operands, which is not necessarily the case for overloaded operators. In the case of overloaded operators, you leave someone guessing about everything. They have to read a lot more source code just to understand what you're doing. Contrast that with something like this:

    myString = String.concat(string1, string2, string3);

    Or:

    myString = String.copy(string1);
    myString.append(string2).append(string3);

    Immutable and mutable. The type is implied. It's very unlikely anyone will EVER confuse what this code does. That's the point, and what operator overloading violates. I don't care how pretty or succinct your code is. If that's really so important to you, please see: http://www.ioccc.org/. They have lots of new lovely tricks for you to use.
  • null 2012-07-27 17:05
    no laughing matter:
    null:
    no laughing matter:
    null:

    Ever heard of linked lists, passing a variable 'by reference', etc.?

    Neither of these use cases require pointers with the properties of C++-pointers: Allowing to point anywhere, allowing to dereference after pointed object ia already freed, allowing to point to null, support of pointer-arithmetics.


    what does the last item in a linked list point to. Does it not point to null?

    Of course not!

    It points to the single instance of the Null-Object!


    A pointer is simply a variable which is mostly of an integer type. It specifies a memory address where the actual object is stored. If you assign the null pointer to a pointer variable, you make the pointer point to no memory address. (Which makes member access impossible.)


    In C and C++, the keyword was NULL, and what NULL really is is 0. It was decided that "0x0000" was never going to be a valid pointer to an object, and so that is the value which gets assigned to indicate that it is not a valid pointer.

    pointers always point to something, even when "uninitialized". The issue is whether the address they hold is legal for your program to access. The special address zero (aka null) is deliberately not mapped into your address space, so a segmentation fault is generated by the memory management unit (MMU) when it is accessed and your program crashes. But since address zero is deliberately not mapped in, it becomes an ideal value to use to indicate that a pointer is not pointing to anything, hence its role as null. To complete the story, as you allocate memory with new or malloc(), the operating system configures the MMU to map pages of RAM into your address space and they become usable.

    A null object is not really null, it is emtpy.
  • Cbuttius 2012-07-31 10:18
    That is not true, a pointer may look like a number but it isn't defined to be one.

    It is common for an operating system to allow you to store a pointer in a form whereby it fits in a number but that does not guarantee that it has to be physically that way.

    In fact, in C and C++ there is a notion of a "contiguous" buffer which enables you to perform pointer arithmetic, but underneath the scenes, the memory may well be fragmented, just the same way that physical disk space might be even when one increases the "offset".

    This is the job of the kernel.

    It does actually make sense for 0 to be a valid pointer had it not been implemented into the language that 0 has a special meaning (e.g. you can call free or delete or delete[] on a null pointer and it is a no-op).

    C++11 does introduce nullptr as a keyword but will have to remain backwardly compatible so as not to break all existing code.
  • Steve The Cynic 2012-08-01 06:13
    null:
    In C and C++, the keyword was NULL, and what NULL really is is 0. It was decided that "0x0000" was never going to be a valid pointer to an object, and so that is the value which gets assigned to indicate that it is not a valid pointer.

    pointers always point to something, even when "uninitialized". The issue is whether the address they hold is legal for your program to access. The special address zero (aka null) is deliberately not mapped into your address space, so a segmentation fault is generated by the memory management unit (MMU) when it is accessed and your program crashes. But since address zero is deliberately not mapped in, it becomes an ideal value to use to indicate that a pointer is not pointing to anything, hence its role as null. To complete the story, as you allocate memory with new or malloc(), the operating system configures the MMU to map pages of RAM into your address space and they become usable.

    A null object is not really null, it is emtpy.


    Sigh. Another one falls into the trap of assuming everything is the same as what he works with.

    Many small systems don't have MMUs of any sort, and do not crash in any way when address 0x0000 (an apt use of only four hex digits, because they are often limited to just 16 bits of address space) is accessed, either for read or for write. (Also, look up the charming message "null pointer assignment" for more on this. Hint: it's printed after a DOS program exits if offset 0 of the default data segment no longer contains the right canary value, indicating a write to *NULL.)

    AS/400 systems (or whatever it is that IBM calls them now) do not use all-bits-zero as NULL pointers.

    On at least some versions of AIX, there is readable-not-writable memory mapped at address 0x00000000, so programs that read from *NULL will not crash.

    The results of dereferencing a NULL pointer in C and/or C++ are "undefined", and will therefore cause all sorts of grief. In the same vein, on some systems (e.g. AS400), this code will print FALSE.

    void *p;
    

    memset(&p, 0, sizeof(p));

    if( p == NULL )
    printf("TRUE\n");
    else
    printf("FALSE\n");


    Uninitialised pointers might contain a bit pattern that is not and cannot be a valid pointer, and might, when *compared* (not dereferenced), even cause crashes on some hardware, such as one that attempts to load a segmented pointer on x86 where the DPL indicates a ring-zero-only segment, but the current code-segment DPL is ring-three.

    Also, most systems do not call the operating system to allocate memory per-malloc, but instead slice large blocks, because it is more efficient in many ways.
  • The Dude 2012-08-06 05:20
    The comments show me one thing: the real WTF is C++