linuxfreak
linuxfreak

Reputation: 2166

changing the alignment requirement while casting

I get the warning " cast increases required alignment of target type" while compiling the following code for ARM.

char data[2] = "aa";
int *ptr = (int *)(data);

I understand that the alignment requirement for char is 1 byte and that of int is 4 bytes and hence the warning.

I tried to change the alignment of char by using the aligned attribute.

char data[2] __attribute__((aligned (4)));
memcpy(data, "aa", 2);

int *ptr = (int *)(data);

But the warning doesn't go away.

My questions are

  1. Why doesn't the warning go away?

  2. As ARM generates hardware exception for misaligned accesses, I want to make sure that alignment issues don't occur. Is there any other way to write this code so that the alignment issue won't arise?

By the way, when I print alignof(data), it prints 4 which means the alignment of data is changed.

I'm using gcc version 4.4.1. Is it possible that the gcc would give the warning even if the aligned was changed using aligned attribute?

Upvotes: 2

Views: 4308

Answers (1)

Lundin
Lundin

Reputation: 214255

I don't quite understand why you would want to do this... but the problem is that the string literal "aa" isn't stored at an aligned address. The compiler likely optimized away the variable data entirely, and therefore only sees the code as int* ptr = (int*)"aa"; and then give the misalignment warning. No amount of fiddling with the data variable will change how the literal "aa" is aligned.

To avoid the literal being allocated on a misaligned address, you would have to tweak around with how string literals are stored in the compiler settings, which is probably not a very good idea.

Also note that it doesn't make sense to have a pointer to non-constant data pointing at a string literal.

So your code is nonsense. If you still for reasons unknown insist of having an int pointer to a string literal, I'd do some kind of work-around, for example like this:

typedef union
{
  char arr[3];
  int  dummy;
} data_t;

const data_t my_literal = { .arr="aa" };
const int* strange_pointer = (const int*)&my_literal;

Upvotes: 4

Related Questions