0

In C++/C you can do this:

unsigned char A[12];
unsigned int *B;
int *C;
B = malloc(sizeof(unsigned int));
C = malloc(2*sizeof(int));
A[0] = *B;
A[4] = *C;
//Then go on to access A byte by byte.

I was wondering if this was possible in LLVM-IR, or would it immediately complain of a problem with types. Was about to dive into this, but thought I would see if anyone has tried this particular example. Would I GEP A's 0th location as a i8* and then B and C's as a i32*. I'm a bit confused as how to proceed, if this is at all possible.

Thanks ahead of time.

UPDATE:

Ok, if I instead added initialization for *B and C[0], C[1], it would the answer change for LLVM-IR /C / C++?

redratio1
  • 5
  • 4
  • 1
    Assuming you fix the bit about not initializing `*B` and `C[0]` and `C[1]`, all this does is take the `unsigned int` (or `int` respectively) pointed to by `B` or `C`, truncate it to `char` size, and assign it to a slot in the `A` array. You should get a warning about loss of precision, assuming you aren't ignoring all warnings, but due to the standard conversions between integral types, this is legal, if somewhat questionable... – twalberg Jan 13 '14 at 22:29
  • @twalberg; Thanks, that makes sense/ I was assuming that since there was continuous memory I could get away with placing the larger type into the array. and have the bits extended across A's allocation. – redratio1 Jan 13 '14 at 22:36

2 Answers2

1

LLVM has the bitcast instruction which is often used to convert one type of pointer to another type of pointer - e.g., i32* to i8*.

So for example, if you want to access the 3rd byte of a 4-byte number, doing the following is perfectly legitimate:

%bytes = bitcast i32* %num to i8*
%third_byte = getelementptr i8* %bytes, i32 2

Just keep in mind the endianess when you do stuff like that.

And yes, you can use this technique to obtain pointers to specific locations in an array and store and load values from there, enabling you to do duplicate your entire example.

Oak
  • 26,231
  • 8
  • 93
  • 152
0

No. This is not possible in C/C++ too. You should not assign an uninitialized variable to another variable. It invokes undefined behavior. *B and *c are uninitialized.

haccks
  • 104,019
  • 25
  • 176
  • 264
  • 1
    *"You can't"* I think this is very restrictive language, because you can do it, but has undefined behavior. – Manu343726 Jan 13 '14 at 22:19
  • @Manu343726; Agreed. Changed that. – haccks Jan 13 '14 at 22:20
  • Ok, however if B and C were initialized, it would have a well defined behavior? – redratio1 Jan 13 '14 at 22:22
  • @redratio1 in that case, it breaks the [strict aliasing rule](http://stackoverflow.com/questions/98650/what-is-the-strict-aliasing-rule) I think. – Manu343726 Jan 13 '14 at 22:23
  • @redratio1; I think what you want to do is `B = A` and `C = (A+4)`, isn't it? – haccks Jan 13 '14 at 22:25
  • @haccks; Basically what I want to do is take a 32 bit result from a previous hash, and a max 2 x 32 bit value. Have them in an array so I can walk through it byte by byte. – redratio1 Jan 13 '14 at 22:27