Thread: Bit Counting Disparity?

  1. #1
    Registered User
    Join Date
    Dec 2011
    Posts
    795

    Bit Counting Disparity?

    Having nothing else to do, I decided to write a simple C program that checked the amount of bytes in certain variables, without using sizeof.

    This code works and displays the correct values on both my mac and linux box:

    Code:
    
    #define count(x,y) for(x=1; x; x <<= 1) y++
    
    
    void verify_bits_count() {
        
        char    chr_init = 0;
        short    sht_init = 0;
        int        int_init = 0;
        long    lng_init = 0;
    
    
        short chr_ret = 0, sht_ret = 0, int_ret = 0, lng_ret = 0;
        
        count(chr_init, chr_ret);
        count(sht_init, sht_ret);
        count(int_init, int_ret);
        count(lng_init, lng_ret);
        
        printf("\n\nbit count\n\n");
        printf("char has %d bytes\n",chr_ret/8);
        printf("short has %d bytes\n",sht_ret/8);
        printf("int has %d bytes\n",int_ret/8);
        printf("long has %d bytes\n",lng_ret/8);
        
        
    }
    However, this code only works on my mac (which afaik has the same architecture as my linux):

    Code:
    short loop_test(char *chr_char) {
        short chr_val = 0;
        int chr_ret = 0;
        for (chr_val = 0; chr_val <= 100; chr_val++) 
            chr_ret += (chr_char[chr_val] == -1 ? 1 : 0);
        return chr_ret;
    }
    
    
    #define loop_tst(cc,cv,cr) for (cv = 0; cv <= 100; cv++) cr += (cc[cv] == -1 ? 1 : 0);
    
    
    void verify_bits_loop() {
        char *dst = malloc(100);
        short chr_ret = 0;
        short sht_ret = 0;
        short int_ret = 0; 
        short lng_ret = 0;
        
        char chr_val = 0xFFFFFFFFFFFFFFFF;
        memset(dst, 0x00, 100);
        strcpy(dst, (char *)&chr_val);
        loop_tst(dst,chr_val,chr_ret);
        
        short sht_val = 0xFFFFFFFFFFFFFFFF;
        memset(dst, 0x00, 100);
        strcpy(dst, (char *)&sht_val);
        loop_tst(dst,sht_val,sht_ret);
        
        
        int int_val = (int)0xFFFFFFFFFFFFFFFF;
        memset(dst, 0x00, 100);
        strcpy(dst, (char *)&int_val);
        loop_tst(dst,int_val,int_ret);
        
        
        long lng_val = 0xFFFFFFFFFFFFFFFF;
        memset(dst, 0x00, 100);
        strcpy(dst, (char *)&lng_val);
        loop_tst(dst, lng_val, lng_ret);
        
        printf("\n\nloop test\n\n");
        printf("char has %d bytes\n",chr_ret);
        printf("short has %d bytes\n",sht_ret);
        printf("int has %d bytes\n",int_ret);
        printf("long has %d bytes\n",lng_ret);
        
    }


    The difference is in the "char", where the mac correctly displays it as 1 byte, whereas the linux interprets it as two in the last function. Any ideas why it does that?

  2. #2
    Registered User
    Join Date
    Mar 2011
    Posts
    546
    char chr_val = 0xFFFFFFFFFFFFFFFF;
    memset(dst, 0x00, 100);
    strcpy(dst, (char *)&chr_val);
    loop_tst(dst,chr_val,chr_ret);


    what terminates the strcpy? you have a single char with the value 0xff and it may or not have a zero next to it to terminate. so you will get results based on whatever happens to be the memory setup.

    edit: your loop will skip over non-ff's in memory until it hits more FF's and eventually a 0 to terminate.
    Last edited by dmh2000; 12-12-2011 at 06:31 PM.

  3. #3
    Registered User
    Join Date
    Dec 2011
    Posts
    795
    Quote Originally Posted by dmh2000 View Post
    what terminates the strcpy? you have a single char with the value 0xff and it may or not have a zero next to it to terminate. so you will get results based on whatever happens to be the memory setup.
    I don't understand why there would be variability in a 1-byte storage type. In the context of structs, they're assumed to be the smallest units (excluding bitfields), and therefore, you cannot __attribute__((__packed__)) them. By the same logic, how would a zero be able to fit in?

    Also, on a bit level, (unless I'm thinking about it completely wrong) when the char is set to 0xFF....., all of the bits are set to 1?

  4. #4
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,318
    What it tries to do in every case is to buffer overrun the xxx_val variable.
    If you declare the xxx_val variables as an array of two items, then it should be okay.
    Note that a much cleaner way would be to initialise both entries in the array to zero and then do this to flip all the bits into ones:
    Code:
    xxx_val[0] = ~xxx_val[0];
    Of course once you have an array of two items then the sizeof is easily determined by subtracting the address of the first item from the second (after casting both addresses to char*).
    My homepage
    Advice: Take only as directed - If symptoms persist, please see your debugger

    Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Counting
    By r_1481 in forum C Programming
    Replies: 4
    Last Post: 11-25-2011, 02:55 PM
  2. BST Counting
    By m0ntana in forum C Programming
    Replies: 6
    Last Post: 05-11-2007, 05:37 AM
  3. Counting Numbers in Array, not counting last number!
    By metaljester in forum C++ Programming
    Replies: 11
    Last Post: 10-18-2006, 11:25 AM
  4. counting
    By threahdead in forum C Programming
    Replies: 0
    Last Post: 10-19-2002, 10:33 AM
  5. Counting
    By simhap in forum C++ Programming
    Replies: 5
    Last Post: 10-08-2001, 04:06 PM