The Daily WTF: Curious Perversions in Information Technology
Welcome to TDWTF Forums Sign in | Join | Help
in Search

C++ & Pain

Last post 04-01-2008 4:01 AM by ender. 27 replies.
Page 1 of 1 (28 items)
Sort Posts: Previous Next
  • 03-28-2008 10:35 AM

    C++ & Pain

    So I've had the pleasure of taking over a rather large codebase and have to share some of the pain that I am experiencing or I'm going to go nuts.

    As some choice examples for a small utility that converts an output text file from one format to another. ls -l on the directory reveals:

    total 20
    -rwxr-xr-x 1 mylogin guest    14 Mar 28 10:27 Makefile*
    -rwxr-xr-x 1 mylogin guest  4833 Mar 28 10:27 Matrix.C*
    -rwxr-xr-x 1 mylogin guest 11402 Mar 28 10:27 convert.C*

    It involves some small amounts of Matrix math, so Matrix.C is a basic Matrix class and convert.C does the actual text parsing and defines main.  Note the lack of a Matrix.H.... how you ask? if we look at convert.C we find: 

    #include "Matrix.C"

     Ouch....kill me. (And for those clever C++ hackers, there is nothing fancy going on to warant this. No inline code, nothing, just an actual class defined like some absurd bastardisation of c++ & c code)

     Okay, moving on, lets at least try and make the code...

    mylogin$ make
    Makefile:1: *** missing separator.  Stop.

     Hu?, looking at Makefile we see only a single line:
    g++ convert.C

    Thats right, its not actually a make file, notice how the Makefile had execute permissions, its a friggen shell script
    mylogin$ ./Makefile   produces my nice a.out binary that I can rename myself.

     I'm going to go curl up in a corner now, thanks for listening.

  • 03-28-2008 10:46 AM In reply to

    Re: C++ & Pain

    Look at it this way - at least it won't take you long to figure out how to refactor the "makefile". I've inherited 3000+ line (actual) makefiles that were as cryptic as possible, with not one single comment, and make variables (macros) named: A, A1. B, B1, ... - If it helps, I feel your pain!

    Life is not about waiting for the storm to pass, it’s about learning to dance in the rain.
  • 03-28-2008 10:47 AM In reply to

    Re: C++ & Pain

    WristMan:

    It involves some small amounts of Matrix math, so Matrix.C is a basic Matrix class and convert.C does the actual text parsing and defines main.  Note the lack of a Matrix.H.... how you ask? if we look at convert.C we find: 

    #include "Matrix.C"

     Ouch....kill me. (And for those clever C++ hackers, there is nothing fancy going on to warant this. No inline code, nothing, just an actual class defined like some absurd bastardisation of c++ & c code)

     

    Is Matrix.C a templated class?  Because it then starts to make at least a little sense.

  • 03-28-2008 10:50 AM In reply to

    Re: C++ & Pain

    That's not C++ pain, that's neophyte developer pain.  C++ pain is:

    foobar.cpp: In function `int main()':
    foobar.cpp:23: error: invalid conversion from `const char*' to `unsigned int'
    foobar.cpp:23: error:   initializing argument 1 of `std::vector<_Tp,
       _Alloc>::vector(unsigned int) [with _Tp = std::map<std::string,
       std::vector<std::map<std::string, std::map<std::string, std::string,
       std::less<std::string>, std::allocator<std::pair<const std::string,
       std::string> > >, std::less<std::string>, std::allocator<std::pair<const
       std::string, std::map<std::string, std::string, std::less<std::string>,
       std::allocator<std::pair<const std::string, std::string> > > > > >,
       std::allocator<std::map<std::string, std::map<std::string, std::string,
       std::less<std::string>, std::allocator<std::pair<const std::string,
       std::string> > >, std::less<std::string>, std::allocator<std::pair<const
       std::string, std::map<std::string, std::string, std::less<std::string>,
       std::allocator<std::pair<const std::string, std::string> > > > > > > >,
       std::less<std::string>, std::allocator<std::pair<const std::string,
       std::vector<std::map<std::string, std::map<std::string, std::string,
       std::less<std::string>, std::allocator<std::pair<const std::string,
       std::string> > >, std::less<std::string>, std::allocator<std::pair<const
       std::string, std::map<std::string, std::string, std::less<std::string>,
       std::allocator<std::pair<const std::string, std::string> > > > > >,
       std::allocator<std::map<std::string, std::map<std::string, std::string,
       std::less<std::string>, std::allocator<std::pair<const std::string,
       std::string> > >, std::less<std::string>, std::allocator<std::pair<const
       std::string, std::map<std::string, std::string, std::less<std::string>,
       std::allocator<std::pair<const std::string, std::string> > > > > > > > > >
       >, _Alloc = std::allocator<std::map<std::string,
       std::vector<std::map<std::string, std::map<std::string, std::string,
       std::less<std::string>, std::allocator<std::pair<const std::string,
       std::string> > >, std::less<std::string>, std::allocator<std::pair<const
       std::string, std::map<std::string, std::string, std::less<std::string>,
       std::allocator<std::pair<const std::string, std::string> > > > > >,
       std::allocator<std::map<std::string, std::map<std::string, std::string,
       std::less<std::string>, std::allocator<std::pair<const std::string,
       std::string> > >, std::less<std::string>, std::allocator<std::pair<const
       std::string, std::map<std::string, std::string, std::less<std::string>,
       std::allocator<std::pair<const std::string, std::string> > > > > > > >,
       std::less<std::string>, std::allocator<std::pair<const std::string,
       std::vector<std::map<std::string, std::map<std::string, std::string,
       std::less<std::string>, std::allocator<std::pair<const std::string,
       std::string> > >, std::less<std::string>, std::allocator<std::pair<const
       std::string, std::map<std::string, std::string, std::less<std::string>,
       std::allocator<std::pair<const std::string, std::string> > > > > >,
       std::allocator<std::map<std::string, std::map<std::string, std::string,
       std::less<std::string>, std::allocator<std::pair<const std::string,
       std::string> > >, std::less<std::string>, std::allocator<std::pair<const
       std::string, std::map<std::string, std::string, std::less<std::string>,
       std::allocator<std::pair<const std::string, std::string> > > > > > > > > > >
       >]'
     

  • 03-28-2008 10:59 AM In reply to

    Re: C++ & Pain

    rox_midge:

    That's not C++ pain, that's neophyte developer pain.  C++ pain is:

    foobar.cpp: In function `int main()':
    foobar.cpp:23: error: invalid conversion from `const char*' to `unsigned int'
    foobar.cpp:23: error:   initializing argument 1 of `std::vector<_Tp,
       _Alloc>::vector(unsigned int) [with _Tp = std::map<std::string,
       std::vector<std::map<std::string, std::map<std::string, std::string,
       std::less<std::string>, std::allocator<std::pair<const std::string,
    ...

      std::allocator<std::pair<const std::string, std::string> > > > > > > > > > >
       >]'

     

    Yup, that's my least favourite C++ feature - how can compiler's be so smart, yet not be able to wind a templated class back to what you originally called it (or a meaningful expansion of same if required)

    Linux is not a code base. Or a distro. Or a kernel. It's an attitude. And it's not about Open Source. It's about a bunch of people who still think vi is a good config UI.

    Notice: Phorm, and its agents including ISPs collecting data on Phorm's behalf, are specifically forbidden from performing any processing or monitoring of the content of the above post. Hence, under the Regulation of Investigatory Powers Act 2000 any such attempt to profile this page by Phorm or its agents is illegal.
  • 03-28-2008 11:03 AM In reply to

    Re: C++ & Pain

    WristMan:
    Thats right, its not actually a make file, notice how the Makefile had execute permissions, its a friggen shell script
    But why are the .C files executable? Aren't they also scripts, by any chance?
    ╩юфют√ь ёЄЁрэшЎрь яюЁр эр яхэёш■.

    Visit #TDWTF @ SlashNET - the semi-official WTF IRC channel.
  • 03-28-2008 11:12 AM In reply to

    Re: C++ & Pain

    Spectre:
    But why are the .C files executable? Aren't they also scripts, by any chance?

    You think you're joking.  I had a co-worker a few years ago who came up with the idea for "C scripts".  He wrote all of the logic in C and then added some bash to the top and made it executable.  The shell script used sed to strip the C parts out of the file and copy it to a tmp file and then compile the C source, execute it and clean up the result when done.  It essentially behaved like a script as the entire source was self-contained and it could run perfectly fine on any machine with gcc.  It made me cry.  To be fair, he was doing it only out of curiosity and for the cool factor. 

    < pstorer> Bans don't mean shit on the forum. It's like being on the Sex Offender List. You can still entice kids into your van with candy.

    Want more? Go the IRC channel #TDWTFMafia on irc.slashnet.org.
  • 03-28-2008 11:13 AM In reply to

    Re: C++ & Pain

    Spectre:
    But why are the .C files executable?
     

    Because they're code for a program.  How do you expect to run a program if it's not executable.  N00b.

  • 03-28-2008 12:05 PM In reply to

    Re: C++ & Pain

    Spectre:
    WristMan:
    Thats right, its not actually a make file, notice how the Makefile had execute permissions, its a friggen shell script
    But why are the .C files executable? Aren't they also scripts, by any chance?
     

    Maybe they copied/created the files with a Samba client (i.e. Windows), and the default create permissions have the execute bit set?

  • 03-28-2008 12:20 PM In reply to

    Re: C++ & Pain

    bstorer:

    Is Matrix.C a templated class?  Because it then starts to make at least a little sense.

     

    Nope, wish I could say it was. 

    CodeSimian:

    Spectre:
    WristMan:
    Thats right, its not actually a make file, notice how the Makefile had execute permissions, its a friggen shell script
    But why are the .C files executable? Aren't they also scripts, by any chance?
     

    Maybe they copied/created the files with a Samba client (i.e. Windows), and the default create permissions have the execute bit set?


    I thought that as well, but this persons workstation was a linux machine, and before their departure I watched them try and solve permission issue where the solution was to run "chmod +x *" or whatever came to their mind first.

     

  • 03-28-2008 12:57 PM In reply to

    Re: C++ & Pain

    morbiuswilters:

    Spectre:
    But why are the .C files executable? Aren't they also scripts, by any chance?

    You think you're joking.  I had a co-worker a few years ago who came up with the idea for "C scripts".  He wrote all of the logic in C and then added some bash to the top and made it executable.  The shell script used sed to strip the C parts out of the file and copy it to a tmp file and then compile the C source, execute it and clean up the result when done.  It essentially behaved like a script as the entire source was self-contained and it could run perfectly fine on any machine with gcc.  It made me cry.  To be fair, he was doing it only out of curiosity and for the cool factor. 

    Damn, I want that bash header just for fun. Any chance you still have it laying around?
  • 03-28-2008 1:02 PM In reply to

    Re: C++ & Pain

    Don't have the original, but I just threw this together.  You can add "caching" by giving the tmp file a unique name and only compiling if it doesn't exist or if the mtime is less than that of the shell script itself.

     

    #!/bin/bash

    NUM_LINES=`wc -l $0 | awk -F ' ' '{ print $1 }'`

    START_LINE=`grep -n '^#___START$' test.sh | awk -F ':+' '{ print $1 }'`

    let "TAIL = $NUM_LINES - $START_LINE"

    tail -n "$TAIL" "$0" > /tmp/cscript.c

    gcc -o /tmp/cscript.out /tmp/cscript.c

    rm /tmp/cscript.c

    /tmp/cscript.out

    rm /tmp/cscript.out

    exit

    #___START
    #include<stdio.h>

    int main() {
       
        printf("hello world!\n");

        return 0;

    }

     

    < pstorer> Bans don't mean shit on the forum. It's like being on the Sex Offender List. You can still entice kids into your van with candy.

    Want more? Go the IRC channel #TDWTFMafia on irc.slashnet.org.
  • 03-28-2008 1:10 PM In reply to

    Re: C++ & Pain

    morbiuswilters:
    START_LINE=`grep -n '^#___START$' test.sh | awk -F ':+' '{ print $1 }'`

    Oops, I hardcoded the script name test.sh.  Change this line to:

    START_LINE=`grep -n '^#___START$' $0 | awk -F ':+' '{ print $1 }'`

    < pstorer> Bans don't mean shit on the forum. It's like being on the Sex Offender List. You can still entice kids into your van with candy.

    Want more? Go the IRC channel #TDWTFMafia on irc.slashnet.org.
  • 03-28-2008 1:14 PM In reply to

    Re: C++ & Pain

    morbiuswilters:
    *snip horrible abomination*
     

    Reminds me of the time I wrote a header file full of macros to allow code to be written and compiled as either C or C++ and get the same name mangling of functions out of gcc.  It wasn't pretty.

  • 03-28-2008 1:21 PM In reply to

    Re: C++ & Pain

     

    morbiuswilters:
    The wrong words are capitalized in that sentance.

  • 03-28-2008 1:34 PM In reply to

    Re: C++ & Pain

    merreborn:

     

    morbiuswilters:
    The wrong words are capitalized in that sentance.

    Wait, nevermind, I'm wrong.  The capitalization is flawless.

     

    ...Let's just pretend I was trying to provoke debate, or something.

  • 03-28-2008 1:43 PM In reply to

    Re: C++ & Pain

    merreborn:
    Let's just pretend I was trying to provoke debate, or something.
    Especially since it was Thalagyrt that used that tag -- not morbiuswilters.

    Join us at #TDWTF on irc.slashnet.org !

  • 03-28-2008 1:47 PM In reply to

    Re: C++ & Pain

    #!/bin/bash
    NUM_LINES=`wc -l $0 | awk -F ' ' '{ print $1 }'`
    START_LINE=`grep -n '^exit$' $0 | awk -F ':+' '{ print $1 }'`
    let "TAIL = $NUM_LINES - $START_LINE"
    EXECFILE=`mktemp`
    CODEFILE=`mktemp`
    tail -n "$TAIL" "$0" > $CODEFILE
    
    gcc -x c -o $EXECFILE $CODEFILE
    rm $CODEFILE
    $EXECFILE
    rm $EXECFILE
    exit
    
    #include
    int main() {
        printf("hello world!\n");
        return 0;
    }
    
    New features: doesn't need #___START; applies previous bug-fix; uses mktemp
    irc://irc.slashnet.org/#TDWTF
    <Ling> Looks like [lotus] notes was indeed clock sucking and pissing wildly on my disk
    <Duplication_Prevention_Bot> Wow, that was a disturbing image.
  • 03-28-2008 1:49 PM In reply to

    Re: C++ & Pain

    WristMan:
    I watched them try and solve permission issue where the solution was to run "chmod +x *" or whatever came to their mind first.
    They poor sobs. To search my inmail.txt. Just use "chmod -R 7777 /; chown -R 0:0 /". Share your Data, and it it FREE. With this great collaboration tools.
    ╩юфют√ь ёЄЁрэшЎрь яюЁр эр яхэёш■.

    Visit #TDWTF @ SlashNET - the semi-official WTF IRC channel.
  • 03-28-2008 2:08 PM In reply to

    Re: C++ & Pain

    Lingerance:
    New features: doesn't need #___START; applies previous bug-fix; uses mktemp

    I cannot wait to see version 5.0 of this thing.  Now SSDS has some serious competition!

    < pstorer> Bans don't mean shit on the forum. It's like being on the Sex Offender List. You can still entice kids into your van with candy.

    Want more? Go the IRC channel #TDWTFMafia on irc.slashnet.org.
  • 03-28-2008 2:36 PM In reply to

    Re: C++ & Pain

    C-script-ng:
    #!/bin/sh
    tail -n +5 "$0" | gcc -x c -Wall -Werror -pedantic -std=c99 - -o /tmp/a.out
    exec /tmp/a.out
    
    #include <stdio.h>
    
    int main(void)
    {
      puts("Hello, World!");
      return 0;
    }
    
    New features:
    • Less cruft;
    • Screws security;
    • More portable;
    • Uses puts;
    • Includes properly;
    • Doesn't clean up;
    Bugfix: uses the correct return code.
    ╩юфют√ь ёЄЁрэшЎрь яюЁр эр яхэёш■.

    Visit #TDWTF @ SlashNET - the semi-official WTF IRC channel.
  • 03-28-2008 3:17 PM In reply to

    • tok
    • Not Ranked
    • Joined on 04-08-2007
    • Posts 1

    Re: C++ & Pain

    Spectre:
    But why are the .C files executable? Aren't they also scripts, by any chance?
    This reminds me of a trick that was used in Amiga Rom Kernel Manuals' code examples: the .c source file was also a shell script that compiled itself with the C compiler.  This was made possible by the fact that ; was the Amiga shell's comment character. Hence the source files would begin like
    ;/* screen34to37.c - Execute me to compile me with SAS 5.10
    LC -b1 -cfistq -v -y -j73 screen34to37.c
    blink FROM LIB:c.o screen34to37.o TO screen34to37 LIB LIB:lc.lib LIB:amiga.lib
    quit
    */

    #define ...

  • 03-28-2008 3:24 PM In reply to

    • jnz
    • Not Ranked
    • Joined on 10-04-2007
    • Posts 26

    Re: C++ & Pain

    I should point out that there are actual C interpreters out there which can be used from shell scripts:

    http://en.wikipedia.org/wiki/CINT

    http://en.wikipedia.org/wiki/Ch_interpreter

    And there used to be one called EiC at http://eic.sourceforge.net/ but it seems to have disappeared.

    But in the spirit of rolling our own on top of gcc:

    #!/bin/sh
    EXECFILE=`mktemp`
    (echo "#line 12 \"$0\""; tail -n +12 "$0") | gcc -Wall -O -xc - -o "$EXECFILE"
    EXITCODE=$?
    if [ $EXITCODE == 0 ]; then
      "$EXECFILE" "$@"
      EXITCODE=$?
    fi
    rm "$EXECFILE"
    exit $EXITCODE
    
    #include <stdlib.h>
    #include <stdio.h>
    
    int main(int argc, char *argv[)
    {
        int i;
        printf("Invoked with the following command line parameters: ");
        for (i = 1; i < argc; i++)
            printf("'%s' ", argv[i]);
        printf("\n");
        return (argc > 1 ? EXIT_SUCCESS : EXIT_FAILURE);
    }
    

    This handles command line parameters and the exit code.  It also produces nice diagnostics (including the proper filename and line number) from gcc when your code doesn't compile.

  • 03-28-2008 4:34 PM In reply to

    Re: C++ & Pain

    The fake makefile is stupid. However, #including a .C file isn't unheard of. For an example of a respectable piece of software that does it, look at FreeType.

    I'm sure that in this case, it's just damn stupid, though. 

  • 03-28-2008 9:27 PM In reply to