• (cs) in reply to facetious
    facetious:
    missing:
    As I said *without* assembling it at runtime. sprintf *is* assembling at runtime, its time complexity is scaling with the number of spaces you want.

    If you want to save at runtime, use a single character string and take a slice of it (as described above).

    Or .. I guess .. you could ..

    char SEVEN_SPACES[8] = "       ";
    #define SPACES(x) (SEVEN_SPACES+7-x)
    
    Wow... that's actually very cool :) I'm impressed! :D
  • Anon (unregistered) in reply to newt0311
    newt0311:
    Rob:
    In C string literals have type char *, not const char *, you just aren't allowed to modify them.
    no, char * are perfectly modifiable. Its done all the time. all that a char * means is an array of characters and is the closest C comes to a string. a const char * is also a valid declaration which will cause the compiler to raise an error if any attempt is made to modify it. gcc also gives a warning when a const is assigned to a non-const without a specific declaration to go along with it.
    you missed the point. you can modify a char*, but you aren't allowed to modify a char* that points to a string literal.

    e.g. This might even compile, but its not allowed: char* bob = "bob"; bob[0] = 'j';

    after this bob might point to "job", but it might still point to "bob", or it might even throw an exception, or just crash - that's the thing about undefined behaviour...

  • Baggy McBagster (unregistered) in reply to Anon
    Anon:
    newt0311:
    Rob:
    In C string literals have type char *, not const char *, you just aren't allowed to modify them.
    no, char * are perfectly modifiable. Its done all the time. all that a char * means is an array of characters and is the closest C comes to a string. a const char * is also a valid declaration which will cause the compiler to raise an error if any attempt is made to modify it. gcc also gives a warning when a const is assigned to a non-const without a specific declaration to go along with it.
    you missed the point. you can modify a char*, but you aren't allowed to modify a char* that points to a string literal.

    e.g. This might even compile, but its not allowed: char* bob = "bob"; bob[0] = 'j';

    after this bob might point to "job", but it might still point to "bob", or it might even throw an exception, or just crash - that's the thing about undefined behaviour...

    'Allowed'? 'Allowed'?? This is C, for heaven's sake! If you can't go in and modify a byte because you just know what that byte should be, why are you programming in C in the first place? The point is that people can, and do, write to string literals in C. They use them as handy buffers. To pad to 30 spaces wide, they declare a literal string of 30 spaces and then sprintf into it, and it works perfectly! Almost every time!

    To heck with this silliness of 'allowed'! In C, it's all about what you CAN DO!

    Now, if you'll excuse me, I'm going to create a loop by simply having a bit of code that modifies CS:IP directly! Because I CAN!

    Naw, I'm kidding. I'm going to write some C#.

  • JDS (unregistered)

    I don't see the WTF. Obviously whoever programmed this needed optimized access to strings that are N spaces. That is no WTF by itself, so how would you do it?

    Keep in mind that in native C++ you cannot have a function that dynamically allocates a string buffer without requiring the user of said function deallocate it (and doing that would be a true WTF).

    This array of N-spaced strings works like a function (with a max limit, but there might not be a need for more). Now, in C# or any garbage collected environment this would be a WTF, but not in C++.

  • brendan (unregistered) in reply to Baggy McBagster
    Baggy McBagster:
    Anon:
    newt0311:
    Rob:
    In C string literals have type char *, not const char *, you just aren't allowed to modify them.
    no, char * are perfectly modifiable. Its done all the time. all that a char * means is an array of characters and is the closest C comes to a string. a const char * is also a valid declaration which will cause the compiler to raise an error if any attempt is made to modify it. gcc also gives a warning when a const is assigned to a non-const without a specific declaration to go along with it.
    you missed the point. you can modify a char*, but you aren't allowed to modify a char* that points to a string literal.

    e.g. This might even compile, but its not allowed: char* bob = "bob"; bob[0] = 'j';

    after this bob might point to "job", but it might still point to "bob", or it might even throw an exception, or just crash - that's the thing about undefined behaviour...

    'Allowed'? 'Allowed'?? This is C, for heaven's sake! If you can't go in and modify a byte because you just know what that byte should be, why are you programming in C in the first place? The point is that people can, and do, write to string literals in C. They use them as handy buffers. To pad to 30 spaces wide, they declare a literal string of 30 spaces and then sprintf into it, and it works perfectly! Almost every time!

    To heck with this silliness of 'allowed'! In C, it's all about what you CAN DO!

    Now, if you'll excuse me, I'm going to create a loop by simply having a bit of code that modifies CS:IP directly! Because I CAN!

    Naw, I'm kidding. I'm going to write some C#.

    the problem is that some compilers will optimize same string literals in to one instance of that string, which means that if you have two different peices of code depending on a literal, and you change one, the other will be change as well.

    JDS:
    I don't see the WTF. Obviously whoever programmed this needed optimized access to strings that are N spaces. That is no WTF by itself, so how would you do it?

    Keep in mind that in native C++ you cannot have a function that dynamically allocates a string buffer without requiring the user of said function deallocate it (and doing that would be a true WTF).

    This array of N-spaced strings works like a function (with a max limit, but there might not be a need for more). Now, in C# or any garbage collected environment this would be a WTF, but not in C++.

    before this part of the program, the buffer (pDuration) is already allocated, which means that the char array waste of space and the char array also can also have a possible problem of buffer overflow/underflow.

  • Oli (unregistered)

    I've far too much time on my hands. Anyone want to expand this for subtraction, multiplication and some floating point?

    char *pSpaceChar[10] = {

      "",             // No Space Characters
    
      " ",            // One Space Character
    
      "  ",           // Two Space Characters
    
      "   ",          // Three Space Characters
    
      "    ",         // Four Space Characters
    
      "     ",        // Five Space Characters
    
      "      ",       // Six Space Characters
    
      "       ",      // Seven Space Characters
    

    //Oli " ", // EightSpace Characters

      "         "};    // Nine Space Characters
    

    char del="#";

    int spacetoint(char *a) { int num=0, pow=1; for (int i=strlen(a); i>0; i--) { if (a[i]!=del) continue; for (int j=9; j>0; j++) if (strcmp(a+i, pSpaceChar[j])==0) { num += (strlen(pSpaceChar[j])*pow) pow++; } } return num; }

    char *inttospace(int x) { char *str; int pow=1, fig;

    while ((fig = x / pow))
    {
    	str = (char *) realloc(strlen(pSpaceChar[fig])+1)
    	str = strcat(str, '#');
    	str = strcat(str, pSpaceChar[fig]);
    }
    return str;
    

    }

    char *add(char *a, char *b) { int j = spacetoint(a) + spacetoint(b);

    return inttospace(j); }

  • (cs)

    Oh dear does nobody get the fact that (s)printf already has formatting to pad with spaces. I guess there are not enough C programmers here.

    By the way, const has been part of the ANSI-C standard for a long time and you need 2 consts here to define actual constants thus:

    const char * const space_strings[] =
      { 
       //etc
      };
    

    With only the first const you would not be able to modify the strings but you could modify the array to contain different literals / non-writable strings.

    It's also probably another issue of the root of all evil, premature optimisation.

  • sz (unregistered)

    See this example for proper use of the MAYBE construct:

    #define MAYBE "\0"
    
    #define pSpaceChar0 ""
    #define pSpaceChar1 " "
    #define pSpaceChar2 "  "
    #define pSpaceChar3 "   "
    #define pSpaceChar4 "    "
    #define pSpaceChar5 "     "
    #define pSpaceChar6 "      "
    #define pSpaceChar7 "       "
    
    char *SpacesGenerator=
        MAYBE pSpaceChar0
        MAYBE pSpaceChar1
        MAYBE pSpaceChar2
        MAYBE pSpaceChar3
        MAYBE pSpaceChar4
        MAYBE pSpaceChar5
        MAYBE pSpaceChar6
        MAYBE pSpaceChar7;
    
    int SuperMan(int n) {
        switch(n) {
            case 0:
                return 1; //SEE BUG #3141592654
            case 1:
                return 1*(1+1)/2+1;
            case 2:
                return 2*(2+1)/2+1;
            case 3:
                return 3*(3+1)/2+1;
            case 4:
                return 4*(4+1)/2+1;
            case 5:
                return 5*(5+1)/2+1;
            case 6:
                return 6*(6+1)/2+1;
            case 7:
                return 7*(7+1)/2+1;
            default:
                return (char)MAYBE[0];
        }
    }
    
    int main() {
        int i;
        for(i=0;i<8;++i) {
            printf("%s%d\n",SpacesGenerator+SuperMan(i),i);
        }
        return MAYBE;
    }
    
  • (cs) in reply to JDS
    JDS:
    I don't see the WTF. Obviously whoever programmed this needed optimized access to strings that are N spaces. That is no WTF by itself, so how would you do it?

    He is already using printf. So why gum up the works by adding random strings? This isn't any more optimized that using printf for what it is designed to do. As I mentioned before, if the "optimized" string stradles a page, you'll just blow away any sort of performance you gain.

    And besides what would you rather maintain? Don't reinvent the wheel unless you have a really good reason.

  • Anon (unregistered) in reply to JDS
    JDS:
    I don't see the WTF. Obviously whoever programmed this needed optimized access to strings that are N spaces. That is no WTF by itself, so how would you do it?

    Keep in mind that in native C++ you cannot have a function that dynamically allocates a string buffer without requiring the user of said function deallocate it (and doing that would be a true WTF).

    This array of N-spaced strings works like a function (with a max limit, but there might not be a need for more). Now, in C# or any garbage collected environment this would be a WTF, but not in C++.

    uhh, arent std::string and std::auto_ptr part of any native c++ implementation, and dont they allow you to do just that?

    If you're not using the STL in C++, then you're not writing C++ code, you're writing "C, with classes" code.

  • JDS (unregistered) in reply to Anon

    You're right, the need to call delete can be solved using auto_ptr. But using this approach has the negative of having to reallocate the space character string every time it's asked for (since it's deallocated every time).

    You would also have to wrap them in a class, since auto_ptr calls delete and not delete[]. Maybe there is an equivalent for delete[]? I don't know.

    Still don't think this is enough to warrant a WTF. Even if he's using printf as someone mentioned above. We know nothing about the requirements for optimized code in this example.

  • JDS (unregistered)

    Come to think of it, the guy above is right about the printf thing. He's already using it, so the optimization makes no sense here.

    See, I can admit when I'm wrong. That's why I'm better than all of you. (J/K)

  • noogen (unregistered) in reply to JDS

    public static string PadSpaceRight(string original, int size) { if (size < 0 || size > 7) return "You're sh*t out of luck!"; return string.Format("{0}{1}", original, pSpaceChar(size); }

    ... PadSpaceLeft and so on...

    ironically - CAPTCHA: muhahaha

  • Martin (unregistered)

    If this code is in a mission critical performance point, it's actually the way to do it. Nothing to see here, move along, ofcourse you should go for puts and not sprintf in that case.

    And if any of you really think that those places should have a for loop (insane for performance) or a separate function(are you completely nuts ?) , you should go back to programming a-b-c.

    The code is not a beauty, but performance has its cost.

Leave a comment on “Global Spaces”

Log In or post as a guest

Replying to comment #:

« Return to Article