Thread: Syntax Question for Array in C

  1. #1
    Registered User
    Join Date
    Sep 2007
    Posts
    24

    Syntax Question for Array in C

    Hello. I'm working on a project where I have to use someone's code. I know what this block of code does, I need help with the actual syntax. I'm confused on why the uint32_t is in parenthesis and how the code following that "&flash_array[x] works. Thanks in advance.

    Code:
    const uint32_t flash_block_address[NUM_OF_FLASH_BLOCKS] =
    {
        (uint32_t)&flash_array[248 * 64], 	
        (uint32_t)&flash_array[249 * 64], 	
        (uint32_t)&flash_array[250 * 64], 	
        (uint32_t)&flash_array[251 * 64], 	
        (uint32_t)&flash_array[252 * 64], 	
        (uint32_t)&flash_array[253 * 64], 	
        (uint32_t)&flash_array[254 * 64], 	
        (uint32_t)&flash_array[255 * 64], 	
    };

  2. #2
    Registered User
    Join Date
    Sep 2008
    Location
    Toronto, Canada
    Posts
    1,834
    Whatever the type of flash_array is, (uint32_t) casts the address of the indexed element to another data type - I would assume a 32 bit unsigned integer.
    The statement assigns the eight values to the array flash_block_address[NUM_OF_FLASH_BLOCKS].

  3. #3
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    That code sucks. Why is it casting pointers to integers for no good reason?
    Code:
    //try
    //{
    	if (a) do { f( b); } while(1);
    	else   do { f(!b); } while(1);
    //}

  4. #4
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    It is just converting the series of addresses (&flash_array[248 * 64] etc) to uint_32 (which, from its name, is an unsigned 32 bit integral type).

    That is dangerous in general. It will certainly cause any code which uses those values to break on a 64 bit system - because, presumably, any code which uses flash_block_array will need to convert those uint32_t's back to pointers. Pointers are not guaranteed to survive with their value unchanged in a round--trip conversion (pointer to any integral type back to pointer).

    It would be better if the array was of a pointer type (i.e. a pointer to whatever type the elements of flash_array are). No need for the type conversions, and any code which uses elements of flash_block_address will be guaranteed to work (without having to convert a uint32_t back to a pointer) as long as flash_array contains enough elements to match the initialisation.
    Right 98% of the time, and don't care about the other 3%.

    If I seem grumpy or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Buttercup, and read this, this, and this before posting again.

  5. #5
    Registered User
    Join Date
    Jan 2009
    Posts
    1,485
    uint32_t is part of C99 and is defined in stdint.h, it is indeed a 32 bit unsigned integer.

  6. #6
    Registered User
    Join Date
    Aug 2007
    Location
    MD, USA
    Posts
    71
    Take a look at these warnings I get in this sample usage of what you posted:
    Code:
    #include <stdio.h>
    #include <stdint.h>
    
    #define NUM_OF_FLASH_BLOCKS 8
    
    char flash_array[300 * 64];
    
    int main(void)
    {
    
      const  uint32_t flash_block_address[NUM_OF_FLASH_BLOCKS] =
      {
        (uint32_t)&flash_array[248 * 64]    /*  <---warning */
      };
    warning: cast from pointer to integer of different size
    warning: initializer element is not computable at load time

    A pointer is not a regular integer,
    It is a specific sized integer determined by the system.
    On my system it is 8 bytes. (64 bits)
    If I were to chop off half of the bits to make it a uint32_t
    it would certainly NOT be the same location in memory.
    So just let the system decide what size a pointer is.

    YOU WANT an array of pointers to the proper type.
    Here I make it char * to match the type of flash_array[]:
    Code:
      const  char * flash_block_address[NUM_OF_FLASH_BLOCKS] =
      {
        &flash_array[248 * 64],
        &flash_array[249 * 64]
      };
    
      flash_array[248 * 64] = 0x7d;
    
      printf("%02x \n", *flash_block_address[0] );
    
      return 0;
    }
    out:
    Code:
    >  gcc -Wall -W -pedantic casting_Q.c -o casting_Q.bin
     
    >  ./casting_Q.bin
    7d
    So yours needs to be matched to the flash_array[] in your code in the same way.

  7. #7
    Registered User
    Join Date
    Jan 2009
    Posts
    1,485
    If you must use an integer type for a pointer for some reason, there is a uintptr_t also defined in stdint.h that is the same size as a pointer.

  8. #8
    Registered User
    Join Date
    Aug 2007
    Location
    MD, USA
    Posts
    71
    Out of curiosity, what could you do with that address cast to integer?

  9. #9
    Registered User
    Join Date
    Jan 2009
    Posts
    1,485
    Quote Originally Posted by HowardL View Post
    Out of curiosity, what could you do with that address cast to integer?
    I don't know, it's there never the less, and is guaranteed to be the size of a void* if you find a reason to do it.

  10. #10
    Registered User
    Join Date
    Sep 2007
    Posts
    24
    Thanks for the responses, makes sense now. This code was for an embedded platform of which I do not know any details, so it's very hardware specific. I will be porting it to a different micro-controller.

  11. #11
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    Quote Originally Posted by Subsonics View Post
    uint32_t is part of C99 and is defined in stdint.h, it is indeed a 32 bit unsigned integer.
    Sure. But the OP did not provide any information to suggest usage of C99 or its stdint.h, and types like uint32_t are defined fairly commonly in some pre-C99 libraries. Such libraries provided the justification for adding uint32_t and similar types to C99.

    The code sample would be better rewritten as an array of pointers, rather than an array of any integral types - that would make life easier for any code which uses the array. Particularly when porting between hardware.

    The only possible exception I can think of to that advice is a couple of very obscure C compilers (which supported a subset of the language, and targeted a very specific hardware) that did not support arrays of pointers.
    Last edited by grumpy; 05-25-2012 at 08:21 PM.
    Right 98% of the time, and don't care about the other 3%.

    If I seem grumpy or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Buttercup, and read this, this, and this before posting again.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Array Syntax Versus Pointer Syntax
    By LyTning94 in forum C++ Programming
    Replies: 6
    Last Post: 12-06-2011, 10:56 AM
  2. 2D array syntax
    By sairakhalid in forum C++ Programming
    Replies: 3
    Last Post: 11-03-2010, 04:38 PM
  3. Syntax for constant array of array pointers
    By BMintern in forum C Programming
    Replies: 4
    Last Post: 05-14-2008, 08:21 AM
  4. linked list inside array of structs- Syntax question
    By rasmith1955 in forum C Programming
    Replies: 14
    Last Post: 02-28-2005, 05:16 PM
  5. Which array is correct syntax in C
    By DiepVien_007 in forum C Programming
    Replies: 2
    Last Post: 03-25-2003, 12:18 PM