GCC Intrinsics bswap64 (C Programming)

Discussion in 'Mac Programming' started by MorphingDragon, Jul 24, 2012.

  1. macrumors 603

    MorphingDragon

    Joined:
    Mar 27, 2009
    Location:
    The World Inbetween
    #1
    I'm looking at using bswap64 to help speed up string reversing but I'm having issues getting the type system to play nicely.

    Code:
    test.c: In function ‘main’:
    test.c:19: warning: cast to pointer from integer of different size
    test.c: At top level:
    test.c:27: error: conflicting types for ‘storeLong’
    test.c:19: note: previous implicit declaration of ‘storeLong’ was here
    test.c:40: error: conflicting types for ‘extractLong’
    test.c:10: note: previous implicit declaration of ‘extractLong’ was here
    
    This is my current test/play code, it takes "abcdefgh" and prints "hgfedcba":

    Code:
    #include <stddef.h>
    #include <stdio.h>
    #include <stdint.h>
    
    int main(int argc, char *argv[]) {
        // Example Word
         char* word = "abcdefgh";
    
        // Get long representation
         int64_t num = extractLong(word, 0);
        
        // Print String 
         printf("%s\n", num);
    
        // Perform ByteSwap
         num = __builtin_bswap64(num); 
          
        // Store Swap back into string
         word = (char*) storeLong(word, 0, num);
    
        // Print String
         printf("%s\n", num);
    
         return 0;
    }
    
    void storeLong(char* array, size_t off, int64_t val)
    {
          array[off + 0] = (char)((val & 0xff00000000000000L) >> 56);
          array[off + 1] = (char)((val & 0x00ff000000000000L) >> 48);
          array[off + 2] = (char)((val & 0x0000ff0000000000L) >> 40);
          array[off + 3] = (char)((val & 0x000000ff00000000L) >> 32);
          array[off + 4] = (char)((val & 0x00000000ff000000L) >> 24);
          array[off + 5] = (char)((val & 0x0000000000ff0000L) >> 16);
          array[off + 6] = (char)((val & 0x000000000000ff00L) >>  8);
          array[off + 7] = (char)((val & 0x00000000000000ffL));
    }
    
    int64_t extractLong(char* array, size_t off)
    {
          int64_t a = array[off+0] & 0xff;
          int64_t b = array[off+1] & 0xff;
          int64_t c = array[off+2] & 0xff;
          int64_t d = array[off+3] & 0xff;
          int64_t e = array[off+4] & 0xff;
          int64_t f = array[off+5] & 0xff;
          int64_t g = array[off+6] & 0xff;
          int64_t h = array[off+7] & 0xff;
          return (a<<56 | b<<48 | c<<40 | d<<32 | e<<24 | f<<16 | g<<8 | h);
    }
    
     
  2. macrumors G5

    gnasher729

    Joined:
    Nov 25, 2005
    #2
    You need a function prototype before calling the function.

    So when you call the function without a prototype, you get a warning (which should be an error) and the compiler guesses the prototype. Then later on it complains again because the guess doesn't match the actual function.

    And functions not used outside a file should always be static. Makes life a lot easier once your project grows.

    And what is %s for? Not for integers of any size.
     
  3. thread starter macrumors 603

    MorphingDragon

    Joined:
    Mar 27, 2009
    Location:
    The World Inbetween
    #3
    Herpy Derpy

    Except now, this function throws a segmentation fault for strings known to be atleast 8 bytes in size. It does it for the expliccit shifting and the memcpy hack.
    Code:
    #include <stddef.h>
    #include <stdio.h>
    #include <stdint.h>
    #include <string.h>
    
    void storeLong(char* array, size_t off, int64_t val);
    
    ...
    
    void storeLong(char* array, size_t off, int64_t val)
    {
          /*array[off + 0] = (char)((val & 0xff00000000000000L) >> 56);
          array[off + 1] = (char)((val & 0x00ff000000000000L) >> 48);
          array[off + 2] = (char)((val & 0x0000ff0000000000L) >> 40);
          array[off + 3] = (char)((val & 0x000000ff00000000L) >> 32);
          array[off + 4] = (char)((val & 0x00000000ff000000L) >> 24);
          array[off + 5] = (char)((val & 0x0000000000ff0000L) >> 16);
          array[off + 6] = (char)((val & 0x000000000000ff00L) >>  8);
          array[off + 7] = (char)((val & 0x00000000000000ffL));*/
    
    
          memcpy(array + off, &val, sizeof(int64_t));
    
    
    }
    
    
    
     
  4. macrumors G5

    gnasher729

    Joined:
    Nov 25, 2005
    #4
    You wrote

    Code:
    char* word = "abcdefgh";
    In C / C++ / Objective C, a string literal like "abcdefgh" which is not used to initialise an array of char is implemented as a pointer to an unnamed static array of const char. So what you write is exactly the same as

    Code:
    static const char invisible_word [9] = { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 0 };
    char* word = (char *) &invisible_word [0];
    Any attempt to change the chars that word points to will result in a crash.
     
  5. thread starter macrumors 603

    MorphingDragon

    Joined:
    Mar 27, 2009
    Location:
    The World Inbetween
    #5
    Wow I really do remember nothing about C. :eek:
     
  6. macrumors 603

    Cromulent

    Joined:
    Oct 2, 2006
    Location:
    The Land of Hope and Glory
    #6
    You have a bug here. You call storeLong() in your main() function and store the return value in word which you cast to char*. Yet your definition of the storeLong() function states that it returns void (i.e it does not return a value).
     

Share This Page