2

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?

Ganesh Sittampalam
29.1k4 gold badges82 silver badges102 bronze badges
asked Sep 15, 2014 at 7:03
8
  • Remember that on most platforms int is 32 bits, four bytes. Your string is only two bytes (three is you consider the string terminator). Commented Sep 15, 2014 at 7:08
  • @JoachimPileborg - Yes, that's why I want to get rid of this warning. If the string starts on an odd boundary, it may lead to an unaligned exception. Commented Sep 15, 2014 at 7:17
  • possible duplicate of ARM unaligned memory access workaround Commented Sep 15, 2014 at 14:32
  • 1
    user3629249: Are you kidding me? Do you typecast the address of a data as int rather than int *? Commented Sep 18, 2014 at 6:26
  • 3
    Why the downvote? This here is a perfectly legitimate question, which is not impaired by the fact that the array is too small in space to hold 32 bits. (Are there ARMs with 16 bit word size? In that case the array would be big enough.) Yet the question has -2 points by the time I come here. I will never get how folks here at SO decide their votings. They appear to vote pretty much randomly with a tendency to downvote the most interesting questions and insightful answers and upvote unhelpful answers if they only were the quickest to be dropped. Commented Nov 30, 2016 at 19:45

1 Answer 1

4

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;
answered Sep 15, 2014 at 8:28
Sign up to request clarification or add additional context in comments.

7 Comments

Alright. I don't mean to access a string literal using an int pointer. I just want to be able to cast pointers from one type to another without hitting alignment errors. Lets say, I use memcpy. Now, when the compiler sees aligned(4), it will align the data on a 4 byte boundary, right? But, why do I get the warning?
@linuxfreak You wouldn't get a hardware error unless you tried to access that memory. There is no form of intelligence in the CPU nor in the compiler which examines the contents of the pointer itself. __attribute__ aligned merely aligns the variable itself, so in your case it ensures that the pointer is stored at an aligned address, not the data it points at. As for what you think char uninit_ptr; memcpy(uninit_ptr, ... will do, I have no idea. It will crash & burn on most systems and that's not related to alignment.
I've changed the char* to char array now. Now, the compiler should align data on a 4 byte boundary and hence there should be no warning when casting it to an int *. But, still I get the warning.
const int *strange_pointer = &my_literal.dummy; might be considered better style
a union is a bad example here since we dont have control over how the union is built that is up to the compiler, we hope that it makes that above union 4 bytes and aligned no less, but there are no guarantees.
|

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.