2

I have an array and I want to convert it to an int32_t array.

I tried the code below.

int32_t const_data[11];
int8_t buffer[44];

    int k = 0;
    while (k < 11) {
        for (int j = 0; j < 44; j++) {
                const_data[k] = bf.buffer[j];
                k++;
        }
    }
  • 2
    In what [endian form](https://en.wikipedia.org/wiki/Endianness)? Bytes and multi-byte integers are not necessarily interchangeable. – tadman Jun 19 '19 at 16:25
  • 1
    How is that code supposed to work? It appears to be unrelated to your stated aim. What is `size_of_const()` and what is the +12 offset for? Also `0001 0004 0003` is not an unambiguous description of the content - 4 digit octal values suggests 12 bit value not `uint8_t` - or are these character strings representing integers and not 8 bit integers at all? Too much ambiguity to post an answer. – Clifford Jun 19 '19 at 16:28
  • @Clifford good point about the octal values but I assume he meant 0x0001, 0x0004, etc – bigwillydos Jun 19 '19 at 16:52
  • 1
    But even then those would be 16 bits.. – bigwillydos Jun 19 '19 at 16:54
  • Are you just trying to get the compiler to treat `buffer` as `int32_t*`? In this case just cast:`int32_t* const_data = (int32_t*) buffer` – Nomios Jun 19 '19 at 17:43
  • What is your reducing function? – Neil Jun 19 '19 at 18:46

2 Answers2

2

The easiest and most straight forward way is to use a union

#define array_size_int32    11
#define array_size_int8     44

typedef union{
    int32_t const_data[array_size_int32];
    int8_t buffer[array_size_int8];
}my_union_t;

Example usage:

/* initialize union members */
my_union_t my_union = {
    .const_data = {
        0x12345678,
        0x12345678,
        0x12345678,
        0x12345678,
        0x12345678,
        0x12345678,
        0x12345678,
        0x12345678,
        0x12345678,
        0x12345678,
        0x12345678,
    },
};

Example way to print:

uint8_t i;

for(i = 0; i < array_size_int8; i++){

    /* mask off sign extension bits */
    printf("my_union.buffer[%d] = %x\n", i, my_union.buffer[i] & 0xff);

}

You can try the code out here

EDIT:

I should add that this works because the memory size needed to allocate either array is the same and you'll run in to problems if you change the #define's without taking that in to consideration.

For example,

#define array_size_int32    10    //40 bytes
#define array_size_int8     45    //45 bytes
bigwillydos
  • 1,321
  • 1
  • 10
  • 15
  • So this converts my byte_t array to word_t array but in an opposite way. So if byte_t array is 00 00 00 04. Then my word_t array becomes 40000000. How can I fix this so that my word_t array can be 00000004. Thank you! – Mehmet Berk Cetin Jun 19 '19 at 22:31
  • 1
    It's actually 04 00 00 00. When you are printing, it doesn't show you the leading zero unless you specify it to do so (e.g. `printf("%08x\n", my_union.const_data[0]);`) And this has to do with [endianness](https://en.wikipedia.org/wiki/Endianness). I'll explain more in the following comment. – bigwillydos Jun 19 '19 at 23:03
  • If `0x00000004` is your 32 bit value for `my_union.const_data[0]`, then `0x04` is the _least significant byte_, and on a **little endian** machine this will get stored in the lowest position of `my_union.buffer` (position 0). If you set `my_union.buffer[0] = 0x00`, `my_union.buffer[1] = 0x00`, `my_union.buffer[2] = 0x00`, `my_union.buffer[4] = 0x04`, then `my_union.const_data[0]` is going to print `0x04000000` because `0x04` is actually the _most significant byte_. If you want `0x04` to be the _least significant byte_, then store it at `my_union.buffer[0]`. – bigwillydos Jun 19 '19 at 23:08
-1

Below is solution which I used in past for similar problem.

#include <stdio.h>
#include <inttypes.h>
int main(){
    int8_t input[] = {0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08};
    int32_t output[10];
    int count=0;
    for(;count<sizeof(input);count+=sizeof(int32_t)/sizeof(int8_t)){
        output[count] = (int32_t)(*(int32_t*)(&input[count]));
        printf("%x:%x\n",input[count],output[count]);
    }
    return 0;
}

Note: As pointed out by @tadman in comment. You also need to consider endianness of your platform. This solution works well for my problem on platform I was working. Based on your platform you may need to tweak this.

Live Code

Manthan Tilva
  • 3,135
  • 2
  • 17
  • 41
  • I forgot to men that it is in C :( – Mehmet Berk Cetin Jun 19 '19 at 17:43
  • @bigwillydos thanks for pointing out my mistake. Updated for c. – Manthan Tilva Jun 19 '19 at 17:50
  • 3
    `output[count] = (int32_t)(*(int32_t*)(&input[count]));` is a [strict aliasing violation](https://stackoverflow.com/questions/98650/what-is-the-strict-aliasing-rule) and is likely to be a misaligned access. Both of which are undefined behavior. You can not safely take a character address and treat it like another type - `int32_t` in this case. – Andrew Henle Jun 19 '19 at 18:11
  • @ManthanTilva cool, removed the downvote since you corrected that, however, I have not actually reviewed your answer – bigwillydos Jun 19 '19 at 19:03