Thread: casting 4 chars to long int

  1. #1
    Registered User sonnichs's Avatar
    Join Date
    Jul 2011
    Posts
    30

    casting 4 chars to long int

    I am trying to move a 4 byte char buffer into a 32bit integer. No conversion--just move it.
    I have the stretch of code below:
    ==========================================
    char buff[4];
    buff[0] = 0x0B; //load buffer with number 184551986
    buff[1] = 0x00;
    buff[2] = 0x0A;
    buff[3] = 0x32;
    uint32_t adcout;

    adcout = (uint32_t)*buff;
    ===========================================
    looking at acdout in the debugger I would expect to see
    0B000A32
    but i only see
    0000000B
    It clearly is only moving the 1st byte. I thought the compiler would take the buff length into account (and the 32 bit int length).

    What am I missing here?
    Thanks
    Fritz

  2. #2
    Registered User
    Join Date
    Dec 2017
    Posts
    1,631
    You are dereferencing buff (a char*) and assigning it to your int, so you end up with just the first byte. It should be more like:
    Code:
    adcout = *(uint32_t*)buff;
    First, char* buff is cast to uint32_t*, then that pointer is dereferenced, yielding the whole integer.

    If you want the value 184551986, which is 0x0b000a32, then you probably need to store the bytes in reverse (32, 01, 00, 0b) since your machine is probably little-endian. Look it up if you don't know what that means: Endianness - Wikipedia
    A little inaccuracy saves tons of explanation. - H.H. Munro

  3. #3
    Registered User sonnichs's Avatar
    Join Date
    Jul 2011
    Posts
    30
    Thanks for your prompt response John. I am working on PIC18s with the xc compiler which are little-endian. Darn-I have had my share of reversing bytes before!
    Your construct makes sense. I don't know if there is a more streamlined way of doing this (my goal of course is to convert the final ADC readings to float and display them our use them elsewhere in the code).

    I closed my shop for the night but will check this out tomorrow
    cheers
    Fritz

  4. #4
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    Just making a uint32_t pointer to a randomly aligned char buffer risks alignment exceptions.
    Many architectures don't allow you to access multi-byte data types on odd addresses.

    Throw in the mix endianess, and the only portable sane way to do this is like
    Code:
    adcout = ((uint32_t)buff[3]<<24) |
             ((uint32_t)buff[2]<<16) |
             ((uint32_t)buff[1]<<8) |
             ((uint32_t)buff[0]);
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  5. #5
    Registered User
    Join Date
    Feb 2019
    Posts
    1,078
    You could do something like this:
    Code:
    union U {
      char buffer[4];
      uint32_t value;
    };
    
    union U adcout;
    
    adcout.buffer[0] = 0xb;
    adcout.buffer[1] = 0;
    adcout.buffer[2] = 0xa;
    adcout.buffer[3] = 0x32;
    
    // and read from adcout.value.
    This too will avoid the problem Salem is warning you about.

  6. #6
    Registered User
    Join Date
    Feb 2019
    Posts
    1,078
    But.. you don't need that union or to use a pointer to use the 12 bits ADC from PIC18x:
    Code:
      uint32_t value = (ADCRESH << 8) | ADCRESL;
      double flt = (double)value / ((1 << 12) - 1);
    Make sure ADCCON0.FM bit is set.
    (Assuming 'double' has 53 bits of precision here).
    Last edited by flp1969; 03-07-2022 at 04:54 AM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. casting clock_t to unsigned long
    By johnmerlino in forum C Programming
    Replies: 3
    Last Post: 04-19-2014, 11:28 AM
  2. 3 each 8bit chars from a 32bit long int
    By Brucewd in forum C Programming
    Replies: 19
    Last Post: 08-02-2011, 06:27 PM
  3. Casting long int to int
    By KBriggs in forum C Programming
    Replies: 15
    Last Post: 02-22-2011, 03:07 PM
  4. int casting for unsigned chars
    By DarkMasterBosel in forum C++ Programming
    Replies: 4
    Last Post: 01-09-2008, 03:31 AM
  5. Converting a Long to chars[4]
    By Russell in forum C++ Programming
    Replies: 15
    Last Post: 12-18-2002, 06:33 PM

Tags for this Thread