• Chris Becke (unregistered) in reply to Zlodo
    Zlodo:
    Since he declares variables in between statements, this is C++.

    So he could have done:
    stringstream sstr;
    sstr << "blabla " << somevariable << someotherone etc.



    Oh please. The biggest WTF ever is how overloading of shift operators got incorporated into the c++ standard.
  • (cs) in reply to WTFDailyReader
    Anonymous:
    You see - this WTF I don't believe. It must be manufactured - look at the C++ code used. There's some pretty advanced constructs used and I hardly believe that someone who manage to use such intricate code doesn't know sprintf! This, IMHO, is a WTF-wannabe!


    No, the comments make it believable. What you're looking at is the work of a highly advanced practicioner of the "voodoo" or "cargo cult" school of programming. Its philosophy is based on eschewing all attempts to understand language constructs or APIs . Instead, you adapt known receipes, i.e. look through other people's code, take snippets that do things vaguely like what you need, put them together and then fiddle with it in trial-and-error fashion until it works.
  • ZIM (unregistered) in reply to Zlodo
    Zlodo:
    Since he declares variables in between statements, this is C++.
    Not neccesarily. c99 allows variable declaration between statements.
  • black_rock (unregistered) in reply to HAK
    HAK:
    Hooah for reinventing the wheel.  And making it square instead of round, to boot.


    Actually he made it triangular. With sharp edges.
    Hopefully it run over him.
  • Sam Dean (unregistered) in reply to boohiss

    It's in C, yes?

    This means that you can't have a variable declared except at the start of a code block, i.e. usually just after a {

    e.g.

    void my_function(void)
    {
        // Can declare here
        int var1;

        do_something();

        // Can't then declare here
        int var2;


    so, clever* coders realised that you can force the compiler to create a code block like so : 

    void my_function(void)
    {
        // Can declare here
        int var1;

        do_something();

        // Now, it's valid!
        {}
        int var2;



    no, no, no, no, no etc.

    Sam


    * For 'clever', insert your own descriptive expletive.
  • (cs)

    Yeah, I like this don't-know-that-sprintf-exists stuff. Here's another great example using Oracle's "to_char" function which I've found on a production system, too:

    <FONT face="Courier New">EXEC SQL at db_xyz
    SELECT TO_CHAR(:amount,'999999990.V99') INTO :str_amount FROM DUAL;
    strncpy(str_amount, str_amount+1, 12);</FONT>

    Note the strncpy to get rid of the leading blank.

    HAND

    Torsten (from Germany)

     

  • Sam Dean (unregistered) in reply to Sam Dean

    Damn, what I was thinking of was this.

    void my_function(void)
    {
        // Can declare here
        int var1;

        do_something();

        {
           // Declare here
           int var2;
        }

    Nothing like todays wtf. Sorry folks, am very tired.

    Sam

  • anon (unregistered) in reply to Clinton Pierce
    Anonymous:
    I'd like to point out that the general technique has one advantage that sprintf does not: you can allocate exactly the amount of memory that you need to hold an arbitrarily formatted string.

    man asprintf

  • anon (unregistered) in reply to Zlodo
    Zlodo:
    Since he declares variables in between statements, this is C++.

    It isn't, but those spurios pairs of braces apparently trick his C compiler into thinking a new block has started and allowing variable declarations. That's probably what's meant by that strange comment "make the variable".

  • (cs) in reply to Chris Becke
    Anonymous:
    Oh please. The biggest WTF ever is how overloading of shift operators got incorporated into the c++ standard.


    This is not "overloading of shift operator". It would be if the default behavior of that operator in that case would be to shift.
    Most operators have no meaning and can't be used by default on classes, so you can just assign any meaning that you deem useful.
    The fact that thes operators have a default implementation for badiv integer types that shifts them doesn't mean that it cannot have a different meaning for something else.
    Yeah, operator overloading can be missused. As this very website painfully demonstrate every day, you can write asinine crap in any language.

    Listening to C++ detractors, it's like c++ code always use totally counter intuitive operator overloading all over the place, which is quite not true. When C++ code is ugly and hard to maintain, it's rarely for this reason.

    And by the way, I challenge you to explain how the common usage of << as a shift operator and as a streaming operator can be ambiguous and hard to distinguish (barring the fact that you only rarely ever need to shift integer values anyway).
  • anon (unregistered) in reply to RevMike
    RevMike:
    So tell me, what does vector1 * vector2 evaluate to?

    Of course it's shorthand for multiply(vector1, vector2), and you already know perfectly well what that evalutates to, don't you?

  • (cs) in reply to Chris Becke

    Oh my god, kill the "coder" please... [:|] The sad thing is, he was able to make it compile, I wonder how much time he spent only to find the SEEK_SET/SEEK_END values...

    This piece of junk reminds me of some code I encountere a few years ago, it was smth like:

    char *ptr = malloc(1024*1024*10); // Make sure we have enough memory reserved
    if (!ptr) return "";
    sprintf(ptr, "[%02d:%02d:%02d %04d/%02d/%02d -- %s\n", hour, min, sec, year, month, day, incoming_parameter);
    return ptr;

    The size of the buffer I remember very well, it was 10meg of memory it reserved, for a stupid log-function. They didn't understand why the system got slow when a lot of clients connected. In production, this ran in a multi-tasked *nix environment, with normally around 100 concurrent instances running, which could go up to 1000+ when enough clients connected. Since everything was logged, and the machine had 1,5gig of ram, during normal loads, no real problems were encountered, but once the loads went up a bit, welcome to swap-heaven. Once this was fixed, the server could do his job with ease actually not needing more than 512mb...

    Anonymous:
    Zlodo:
    Since he declares variables in between statements, this is C++.

    So he could have done:
    stringstream sstr;
    sstr << "blabla " << somevariable << someotherone etc.



    Oh please. The biggest WTF ever is how overloading of shift operators got incorporated into the c++ standard.

    Indeed... :( Don't like C++ in general. Plain C for straightforward stuff, if it has to be object-oriented, I like to stick to Java. Operator overloading seems nice, but is abused soo often that you can't be absolutely sure what it does. A guy I know once wrote a socket class where "adding" some self-written string-class to it, was actually appending the string to the internal output buffer and send it, while subtracting was only adding to that output buffer. Both returned the original object again. You don't want to see the clever constructions he made with that... Luckily for me (was asked to debug it), operator precedance is the same for all C++ compilers, so I could reconstruct what he was trying to do... Sadly enough, that part worked just fine, so he didn't see any reason to change it...

  • Mark (unregistered) in reply to Chris

    Roman.

    The next handle would have been FILE1V

  • (cs) in reply to brazzy
    brazzy:
    No, the comments make it believable. What you're looking at is the work of a highly advanced practicioner of the "voodoo" or "cargo cult" school of programming. Its philosophy is based on eschewing all attempts to understand language constructs or APIs . Instead, you adapt known receipes, i.e. look through other people's code, take snippets that do things vaguely like what you need, put them together and then fiddle with it in trial-and-error fashion until it works.


    "Cargo Cult Programming".  Brilliant!  Did you coin that phrase?

    I'd like to emphasize that there is a distinction between the cargo cult programmer and the programmers that often learn by adapting recipes.  The main distinction is that cargo cult programmers eschew understanding, where the learn by example crowd modifies examples in thoughtful ways, trying to increase understanding.
  • (cs) in reply to RevMike
    RevMike:
    "Cargo Cult Programming".  Brilliant!  Did you coin that phrase?


    Assuming that the question was not sarcasm: No, it's from the relatively well-known hacker jargon dictionary: http://catb.org/~esr/jargon/html/C/cargo-cult-programming.html


  • asdf (unregistered) in reply to mrsticks1982
    mrsticks1982:

    Anonymous:
    Now, all thats left to do is take this coders face, push it into the monitor showing his code, and say "NO. BAD.".  It's either that, or electric collars...

     

    comments like this help me get through my day. Keep up the good sarcasm!!!



    Someone ban this clown for putting up sig ads
  • (cs) in reply to Drak
    Drak:

    Anonymous:
    Anonymous:
    I particularly liked his filehandle naming convention: FILE1 FILE11 FILE111


    He's using base 1 obviously!

    Hopefully you mean base 2? Base 1 would consist of only 0, seeing as base 10 consists of 0 thru 9 inclusive, but not 10.


    When I used Base 1 in school (a math class, CS only cared about Base 2, with mentions of 8 and 16 where it made the base 2 representation easier), we normally had 1 as the symbol.

    Though sometimes the professor got creative, so one problem probably used something from the Korean alphabet (Only a mathematician would learn a foreign language just to get a different alphabet), and just to prove he could I think 2 was used as the symbol one day.

    In general though, in base-1 math you use 1 as your number, and 0 as the blank.   Base-1 is only slighlty different from base-2 with no blank.   You cannot do Base-1 math without a blank.

  • (cs) in reply to RevMike

    FSCK this forum software - it can't even evaluate quote blocks correctly! I've been forced to cite in dialogue-form!!! X( Did I forget mentioning that moving the cursor with the arrows is a random affair?! You never know where it will go or what parts lines the cursor refuse to go through... WFT?!


    Someone: But then he'd be using shift operators on these things, a WTF in itself.

    Zlodo: It's not the shift operator here, it quite obviously the streaming operator.
    Yeah, its definition of it as a streaming operator isn't hardcoded in the compiler like it's definition as the shifting operator for numeric datatypes, but this is a very specious argument.

    Someone: Oh, operator overloading?  That makes everything much more readable.

    Zlodo:
    I totally agree.
    vector = vector1 + vector2 * scale
    is barely understandable compared to something like
    vector = vector1.add( vector2.multiply( scale ) ).

    RevMike: So tell me, what does vector1 * vector2 evaluate to?

    Whatever you've defined the *-operator to do on the data types in question. It is up to you to use operator overloading judiciouisly.

    Paraphrasing anon: "Of course it's shorthand for vector1.multiply(vector2), and you already know perfectly well what that evalutates to, don't you? "


    Chris Becke: Oh please. The biggest WTF ever is how overloading of shift operators got incorporated into the c++ standard.

    All programs -including operators- are collections of symbols and the manipulations of these, symbols chosen for the convenience of the programmers. The symbols used for bitshifts pictographically imply moving something in a particular direction. Why couldn't this movement be toward a target/recipient (as in stream operations)? Why can the pictograms used for bitshifts have no other intuitive meaning in other contexts? Normally, human beings are experts in decoding contextual meaning in social situations and natural languages. Why wouldn't programmers too be able to handle this? There are other cases you chose not to pick on like distinguishing between bitwise and logical and by single and double ampersands, or using * for pointer declarations, dereferencing and multiplication. It is all a question of convenience and becoming habituated. Conceptually, using the same symbols for bitshift and stream operations is not only unproblematic but also appropriate. All good programmers get accustomed to this *immediately*.

    Funny, first Zlodo said

    Listening to C++ detractors, it's like c++ code always use totally counter intuitive operator overloading all over the place, which is quite not true. When C++ code is ugly and hard to maintain, it's rarely for this reason.

    then two posts later
    KoFFiE says

    Operator overloading seems nice, but is abused soo often that you can't be absolutely sure what it does.

    which was a good example in case of what he hinted at: prejudices and misguided idealism, perhaps coupled with some "see no evil" preferences with his particular Favorite Language (tm).
  • (cs) in reply to brazzy
    brazzy:
    RevMike:
    "Cargo Cult Programming".  Brilliant!  Did you coin that phrase?


    Assuming that the question was not sarcasm: No, it's from the relatively well-known hacker jargon dictionary: http://catb.org/~esr/jargon/html/C/cargo-cult-programming.html




    Not sarcasm.  I'm familiar with "jargon.txt", but I forgot about that entry.
  • Anon (unregistered) in reply to Manni

    Some people don't like to use +=

    I believe its a matter of prefrence much like ++

  • (cs) in reply to Mikademus
    Mikademus:
    FSCK this forum software - it can't even evaluate quote blocks correctly! I've been forced to cite in dialogue-form!!! X( Did I forget mentioning that moving the cursor with the arrows is a random affair?! You never know where it will go or what parts lines the cursor refuse to go through... WFT?!


    Someone: But then he'd be using shift operators on these things, a WTF in itself.

    Zlodo: It's not the shift operator here, it quite obviously the streaming operator.
    Yeah, its definition of it as a streaming operator isn't hardcoded in the compiler like it's definition as the shifting operator for numeric datatypes, but this is a very specious argument.

    Someone: Oh, operator overloading?  That makes everything much more readable.

    Zlodo:
    I totally agree.
    vector = vector1 + vector2 * scale
    is barely understandable compared to something like
    vector = vector1.add( vector2.multiply( scale ) ).

    RevMike: So tell me, what does vector1 * vector2 evaluate to?

    Whatever you've defined the *-operator to do on the data types in question. It is up to you to use operator overloading judiciouisly.

    Paraphrasing anon: "Of course it's shorthand for vector1.multiply(vector2), and you already know perfectly well what that evalutates to, don't you? "


    Chris Becke: Oh please. The biggest WTF ever is how overloading of shift operators got incorporated into the c++ standard.

    All programs -including operators- are collections of symbols and the manipulations of these, symbols chosen for the convenience of the programmers. The symbols used for bitshifts pictographically imply moving something in a particular direction. Why couldn't this movement be toward a target/recipient (as in stream operations)? Why can the pictograms used for bitshifts have no other intuitive meaning in other contexts? Normally, human beings are experts in decoding contextual meaning in social situations and natural languages. Why wouldn't programmers too be able to handle this? There are other cases you chose not to pick on like distinguishing between bitwise and logical and by single and double ampersands, or using * for pointer declarations, dereferencing and multiplication. It is all a question of convenience and becoming habituated. Conceptually, using the same symbols for bitshift and stream operations is not only unproblematic but also appropriate. All good programmers get accustomed to this *immediately*.

    Funny, first Zlodo said

    Listening to C++ detractors, it's like c++ code always use totally counter intuitive operator overloading all over the place, which is quite not true. When C++ code is ugly and hard to maintain, it's rarely for this reason.

    then two posts later
    KoFFiE says

    Operator overloading seems nice, but is abused soo often that you can't be absolutely sure what it does.

    which was a good example in case of what he hinted at: prejudices and misguided idealism, perhaps coupled with some "see no evil" preferences with his particular Favorite Language (tm).


    I'm the "someone" who started the whole thing, mostly for fun.

    C++ operator overloading, like the C pre-processor and C++ mutliple inheritance, are double-edge swords.  When used judiciously by a true expert they can be wonderful tools.  When used by less skilled practitioners, the risk of injury is great.

    Java, for example, eliminated these features to make the language safer from programmers.  Of course, then Sun turned around and introduced J2EE, a spec that a true expert architect can play like a virtuoso, but that anyone less will turn into a WTF.

    Maybe that should be Java's motto:  "Java: making mediocre programmers look good and mediocre architect look bad!"
  • mike (unregistered) in reply to Magnus H
    Anonymous:
    RevMike:

    So tell me, what does vector1 * vector2 evaluate to?

    Hopefully the scalar product of vector1 and vector2 (so that * means · as with numbers). The cross product has to use some other symbol.
    Operator Overloading sucks.

    What you should do is use an IDE that supports MathML (or alike), and will do the convertions into code for you.
  • mike (unregistered) in reply to Mike N
    Anonymous:
    Zlodo:
    Since he declares variables in between statements, this is C++.


    Not necessarily; newer versions of GCC allow that.
    I guessed the {} crap was to fool the compiler.
    No idea if it works.     
  • (cs) in reply to RevMike
    RevMike:
    I'm the "someone" who started the whole thing, mostly for fun.


    I did guess that because of the smiley, but I just like debating (or flaming about) this C++-is-evil-because-you-can-overload-operators thing :)
  • (cs) in reply to tellme
    Anonymous:
    RevMike:

    So tell me, what does vector1 * vector2 evaluate to?


    well, you had your chanches with ada, but thrown it away!
    there, if you do

    double u=v1*v2; // you clearly want a scalar product
    vector u=v1*v2; // you clearly want a cross product

    (sorry, it has to be := )

    but no, ansi said that dumb programmer can't handle the overload of the return value......



    It can actually be done in a way that could arguably be considered close to the frontier between neat and convoluted in C++:


    class VectorProduct;

    class Vector
    {
        (snip)

        const VectorProduct& operator*( const Vector& othervec )
        {
           return VectorProduct( *this, othervec );
        }

        (snip)
    }

    class VectorProduct
    {
        private:
           const Vector& m_v1;
           const Vector& m_v2;

        public:
           VectorProduct( const Vector& v1, const Vector& v2 ) :
              m_v1( v1 ),
              m_v2( v2 )
           {
           }

           operator double()
           {
              // return the dot product between m_v1 and m_v2
            }

           operator const Vector()
           {
              // return the cross product between m_v1 and m_v2
            }
    }


    And then

    double u=v1*v2; // you clearly want a scalar product

    vector u=v1*v2; // you clearly want a cross product

    works.

  • (cs) in reply to Zlodo

    I would normally apologize for the double post, and messing up in the first place and stuff. But since we can't preview, can't edit and the code tag is broken, I would dare say that it's not my fault in the first place. Here we go again without the fucked up html entities showing up:

    Anonymous:
    RevMike:

    So tell me, what does vector1 * vector2 evaluate to?


    well, you had your chanches with ada, but thrown it away!
    there, if you do

    double u=v1*v2; // you clearly want a scalar product
    vector u=v1*v2; // you clearly want a cross product

    (sorry, it has to be := )

    but no, ansi said that dumb programmer can't handle the overload of the return value......



    It can actually be done in a way that could arguably be considered close to the frontier between neat and convoluted in C++:


    class VectorProduct;

    class Vector
    {
        (snip)

        const VectorProduct& operator*( const Vector& othervec )
        {
           return VectorProduct( *this, othervec );
        }

        (snip)
    }

    class VectorProduct
    {
        private:
           const Vector& m_v1;
           const Vector& m_v2;

        public:
           VectorProduct( const Vector& v1, const Vector& v2 ) :
              m_v1( v1 ),
              m_v2( v2 )
           {
           }

           operator double()
           {
              // return the dot product between m_v1 and m_v2
            }

           operator const Vector()
           {
              // return the cross product between m_v1 and m_v2
            }
    }


    And then

    double u=v1*v2; // you clearly want a scalar product

    vector u=v1*v2; // you clearly want a cross product

    works.

  • Defender of the Holy C++ (unregistered) in reply to Suck My Lisp

    > We'll use ">"  for "pairwise multiply" (we'll return a vector) then we'll drink a beer
    > and laugh at the poor saps who'll be maintaining our code when we move on.

    For those who bash operator overloading, I only have the following reply, in Java:

    public int multiply (int v1, int v2)
    {
         return v1 + v2;
    }

    Yes, exactly.

  • #foca (unregistered) in reply to Whackjack
    Whackjack:
    What's up with all the {} embedded in there?
    They're meant to hide the code from Internet Explorer 6, right?

    Please, kill this guy.

  • (cs) in reply to Defender of the Holy C++
    Anonymous:
    > We'll use ">"  for "pairwise multiply" (we'll return a vector) then we'll drink a beer
    > and laugh at the poor saps who'll be maintaining our code when we move on.

    For those who bash operator overloading, I only have the following reply, in Java:

    public int multiply (int v1, int v2)
    {
         return v1 + v2;
    }

    Yes, exactly.


    Why would anyne do that?  We have a built in integer multiplication operator, and the method you describe isn't even a static method.  This makes very little sense...

    Maybe what you really wanted to say is this...

    public class MyInt
    {
        private int theValue;
        .... constructors and other methods skipped.

        public int multiply(MyInt v2)
        {
             return theValue + v2.theValue;
        }
    }

    The problem with operator overloading - and even C++ fans admit this - is that it is possible to overload an operator in an unexpected way AND it not be obvious to a maint. developer that there is even a method call involved.  Java, by eliminating operator overloading (ignoring the String +), insures that the developer always knows that there is a method call involved.
  • (cs) in reply to RevMike
    RevMike:
    The problem with operator overloading - and even C++ fans admit this - is that it is possible to overload an operator in an unexpected way AND it not be obvious to a maint. developer that there is even a method call involved.


    I can't speak for others, but in my experience of working on several, often WTF-ridden and quite large C++ code bases, I don't think I ever seen operator overloading that would give an operator an unexpected meaning.
    Basicaly, I can't remember any case where I encountered any overloading besides equality, arithmetics for custom mathematical types (like vector and matrices), streaming, and dereferencement in smart pointer implementations.

    Not to say that it doesn't happen, but it doesn't seem like such a common occurence as people seem to make it.
    The WTF I see most often in C++ code seem to be more lke stupidely huge classes, useless classes, stupidely huge functions, juggling with pointers, duplicated (but different) implementations of the same things, and generally doing simple things in an hopelessely convoluted way.
    Note that all of these WTF except the pointer stuff can be, and probably are, done with any OO language.
  • nimrand (unregistered)

    Hey, how about a rating system for each day's WTF?  Here's my score:

    Overall Absurdity:   150 (Just look at it.)
    Negative Side-Effects on Application: 175 (filling up disk space, memory leaks, overall slowness)
    Originality:    125 (I've seend other beginner programmers doing some of these things)
    Density:    190 (almost every line of code is a WTF)
    Tilt:     200 (bonus points for the comments)

    Total: 840 "Brilliance" Points

  • x (unregistered)
    Alex Papadimoulis:
    void printf_to_string( int first, char * fomat, ... )
    {
    [...]
      char * string_write_to = va_arg( marker, char * );
    [...]
      double bignumberjustincase = ftell( FILE11 );
    [...]
      read( _fileno( FILE111 ), string_write_to, (short)bignumberjustincase );
    [...]
      int stopHere = (long)string_write_to + (int)0;
    

    stopHere = stopHere + (bignumberjustincase);

    if ( stopHere != 0 ) { ((char*)stopHere)[ 0 ] = '\0'; strcpy( string_write_to + int(bignumberjustincase ), "" );
    va_end( marker ); } }

    I'm surprised no-one's commented on the gem at the end of the function yet...

    So, we take the address we were told to write the string to (string_write_to), cast it to a long (then add 0 for no readily apparent reason), implicitly casting it to an int as we assign it to stopHere. Then add on the size of the output. Finally, if that number isn't zero, we null-terminate the string in two exciting and subtly different ways.

    How can this go wrong? Well, if sizeof(int) < sizeof(char*), we'll crash when executing ((char*)stopHere)[ 0 ] = '\0';

    But more amusingly, for stopHere to be equal to 0, we'd need to have written exactly enough text to the string to have got to the end of the memory (or that subset of it addressable by an int) and wrapped around. Well, I'm glad this genius was smart enough to check for that!

  • (cs) in reply to HAK
    HAK:
    Hooah for reinventing the wheel.  And making it square instead of round, to boot.

    If it were just square it might be fixable, but this one has edges pushed partway into a fractal dimension.
  • Jeff (unregistered)

    Nah, I think this one is contrived.  Google for vfprintf, and the first page also describes vsnprintf.

    And this line too:

    double bignumberjustincase = ftell( FILE11 );

    Almost makes too much sense.

  • anon (unregistered) in reply to Chris Becke

    Anonymous:
    Zlodo:
    Since he declares variables in between statements, this is C++.

    So he could have done:
    stringstream sstr;
    sstr << "blabla " << somevariable << someotherone etc.



    Oh please. The biggest WTF ever is how overloading of shift operators got incorporated into the c++ standard.

    you forgot the parentheses and the comma

  • Chris (unregistered) in reply to Jeff

    Not everyone knows about sprintf. A friend of mine was a good developer, one of the better developers I've know in recent years. Would create strings out of strcpys and strcats and even wrote his own int to hex function. I would through and rewrote all his code one day with sprintfs as it was easier to read one line than 5...

    He asked me "what is this sprintf you are using? and does it work?"

  • (cs) in reply to nimrand
    Anonymous:

    Hey, how about a rating system for each day's WTF?  Here's my score:

    Overall Absurdity:   150 (Just look at it.)
    Negative Side-Effects on Application: 175 (filling up disk space, memory leaks, overall slowness)
    Originality:    125 (I've seend other beginner programmers doing some of these things)
    Density:    190 (almost every line of code is a WTF)
    Tilt:     200 (bonus points for the comments)

    Total: 840 "Brilliance" Points



    Ah no - that should be 840 "Brillance" points.
  • Garcimore (unregistered) in reply to Morgo

    You're idea is interesting, but it's faaaaaaar too complicated for the simple mind of my guy :)

  • (cs) in reply to Chris Becke
    Anonymous:
    Oh please. The biggest WTF ever is how overloading of shift operators got incorporated into the c++ standard.

    I tend to agree in principle because this very point is frequently cited (often by poor programmers) as justification to overload well-known operators to do esoteric tasks.
    Even with that in mind though, I find operator overloading one of C++ greatest strengths because it allows a good programmer to "correct" the default action of an operator from an otherwise dangerous situation.  eg.

    struct tdata
    {
        char* some_string;
    };
    struct tdata str1;
    struct tdata str2;
    str1.some_string = strdup( "a nifty one reference string" );
    str2 = str1;

    The above code is legal in both C and C++.  The "default copy operator" cannot be overridden in C and cannot be disabled - thus, the compiler can never be instructed to prevent the situation.  In C++, one can override the "=" operator and provide in it a "strdup" that ensures every "struct tdata" gets it's own unique copy of the data.
    Obviously this is a contrived example, but it illustrates my point.  Scenarios like this crop up quite frequently.

    My biggest gripe about C++ is that they introduced an ambiguity that C doesn't have; in C a pointer and an array reference are handled in the same way (syntax-wise) though they are considerably different things.  C gets away with this because one cannot produce a single object that has 2 potential type definitions.  This was retained in C++ for backwards compatibility but now a single object can have more than one implicit type conversion.  By overloading the array operator [] and also providing an automatic pointer type cast, the compiler can no longer resolve which of the conversions is the correct one for the scenario where the object is referred to through an array operator - is it intended to implicitly convert through cast and dereference or should it called the overloaded array operator?
    The programmer must resolve the scenario manually by calling the desired operator via call-syntax (eg. object.operator [] ( parm ) ) which is now harder to read and more verbose than the old system!  Worse, neither of the two "operators" can be used directly, making them enssentially worthless.
    Again, a contrived example, but it shits me often.

  • (cs)

    Oh no! He misspelled the variable: temorary_file_name_name.

  • Anonymous (unregistered)

    OMG It's a fake (Obviously)

  • Chris Becke (unregistered) in reply to Xarium
    Xarium:

    I tend to agree in principle because this very point is frequently cited (often by poor programmers) as justification to overload well-known operators to do esoteric tasks.
    Even with that in mind though, I find operator overloading one of C++ greatest strengths because it allows a good programmer to "correct" the default action of an operator from an otherwise dangerous situation.  eg.


    I dislike operator overloading on two grounds :-

    1. I cannot create arbitrary operators.  I can only overload existing operators. This implies strongly to me that operator overloading is just that - an overloading of existing behaviour.

    2. The resulting code doesnt look like C++. Operator overlaoding cannot be used to change the way parameters are passed to functions (or methods). So, than some constructor syntax tricks, one quickly has to revert to "regular" c++ syntax, using brackets and parentheses.

    It looks like another language has been wedged into c++ purely for dealing with streams... fuck, if we are going to start incorporating features from other languages I'd much rather that c++ had been extended to allow multiple returns (int a,b,c=func()). and/or co-routines and generators. And having first class virtual functions (I dont know how to describ this, basically declaring a function (or method) should be synomonous with declaring a function pointer with that name. A simple reassignment would revector all calls to that label).

    All simple things I've only seen in script languages like LUA or Python, but I cant see any impediment to their implementation in a compiled language.
  • (cs) in reply to Chris Becke
    Anonymous:

    It looks like another language has been wedged into c++ purely for dealing with streams... fuck, if we are going to start incorporating features from other languages I'd much rather that c++ had been extended to allow multiple returns (int a,b,c=func()).


    Not that it is something I would necessary want to do, but I think that with a creative redefinition of the comma operator, it could be done :)
  • (cs) in reply to Zlodo
    Zlodo:
    Not to say that it doesn't happen, but it doesn't seem like such a common occurence as people seem to make it.
    The WTF I see most often in C++ code seem to be more lke stupidely huge classes, useless classes, stupidely huge functions, juggling with pointers, duplicated (but different) implementations of the same things, and generally doing simple things in an hopelessely convoluted way.
    Note that all of these WTF except the pointer stuff can be, and probably are, done with any OO language.


    As someone who programs Java for a living, I can tell you that that is EXACTLY what's being done with it (except for most of the pointer juggling, of course).

    However, I still shudder at the thought what people writing that kind of code could do when they are given operator overloading and get excited about its possibilities...
  • (cs) in reply to Chris Becke
    Anonymous:


    Oh please. The biggest WTF ever is how overloading of shift operators got incorporated into the c++ standard.


    To be fair, overloading the shift operators was incorporated into the standard early on because it seemed like a cool example of things that can be done with operator overloading.    At the time few (and no popular) languages supported operator overloading, so there was no general experience to suggest that abusing it is a bad thing.   The standard committee has not done so since then, suggested that as soon as it was realized that operators should not be abused they stopped.

    I recall that someone on the standard committee once saying that they regret introducing it, but I can't find any reference, so take it with a grain of salt.
  • jbode (unregistered)

    :blink blink:

    /rubs eyes

    :blink blink blink:

    I honestly cannot choose between laughing and crying; part of me wants to meet this guy and get him to explain how he came up with this travesty, and part of me just wants to take a baseball bat to him.  Holy Jesus Tapdancing Christ, I've seen bad code before, but that's just...just...

    I am screaming inside, and the one line that has me going bugfuck more than anything else is

    double bignumberjustincase = ftell( FILE11 );

    because there's just no fucking excuse for that.  If you know ftell() exists, then you also know it doesn't return a double, dammit!  That just takes this to a whole new dimension of pain and misery. 

    This guy has way bigger problems than not knowing about sprintf(). 

  • Alun Jones (unregistered) in reply to Zlodo

    Zlodo:

    It can actually be done in a way that could arguably be considered close to the frontier between neat and convoluted in C++:
    8<...snip...>8

    And then

    double u=v1*v2; // you clearly want a scalar product
    vector u=v1*v2; // you clearly want a cross product

    works.

    Sweet.

    What about this:

    vector u=(v1*v2)*v3;

    And your answer may include the words "that should be a syntax error".

  • Alun Jones (unregistered) in reply to Davey Jones

    Anonymous:
    >(can this be used as a random number generator?)

    No, of course not. The docs don't suggest that you can, and seriously; what's the problem for testing that the return value is less than zero?

    Aw man, did I go and forget those "<sarcasm>" tags again?  Could have sworn I had them around here somewhere.

  • (cs) in reply to Alun Jones
    Anonymous:

    Zlodo:

    It can actually be done in a way that could arguably be considered close to the frontier between neat and convoluted in C++:
    8<...snip...>8

    And then

    double u=v1*v2; // you clearly want a scalar product
    vector u=v1*v2; // you clearly want a cross product

    works.

    Sweet.

    What about this:

    vector u=(v1*v2)*v3;

    And your answer may include the words "that should be a syntax error".



    Well, it should be possible to make such ambiguous constructs a compilation error by making the operator* for a VectorProduct private. Then casting would be needed to disambiguate:

    vector u = (double)(v1*v2) * v3, or

    vector u = (vector)(v1*v2) * v3.

    But this is ugly as fuck and defeats the purpose of defining custom operators for readability. That's why I prefer the more straight forward and more readable in the end solution of using a different operator for the cross-product. After all, mathematical notation does so as well, for the same reason.

  • RobK (unregistered) in reply to RevMike

    I think you're missing the point. He wants to format some string data into another string. Pipes ain't needed. If he's too stupid to use sprintf(), he's to stupid to be programming.

Leave a comment on “Printf to String”

Log In or post as a guest

Replying to comment #:

« Return to Article