0
    unsigned char data[] =
    {
        0, 0, 0, 0, 0,
        0, 0, 0, 0, 0
    };

    *((int*) &data[1]) = 0x00256;

this give the warning (see below) can I remove this witout broke the code? by broke, i.e, if I cast to unsigned char* I will copy actually less bytes(not all 32-bit integer) than I'm looking for, right?

warning: cast from 'unsigned char *' to 'int *' increases required alignment from 1 to 4 [-Wcast-align]

The Mask
  • 17,007
  • 37
  • 111
  • 185
  • If you think that warning isn't significant, you've probably never coded for a SPARC before. And you're assigning a literal to an `int` dereference. Like it or not you're moving `sizeof(int)` bytes *somewhere*. – WhozCraig Mar 23 '14 at 04:06
  • But I want to move `sizeof(int)` really. And I want to remove this warning in specific by code but I don't think it's possible – The Mask Mar 25 '14 at 13:16

1 Answers1

1

A few things going on here.

1. Pointer copy.

if p is of type *int then *p = will copy sizeof(int) (4) bytes. Likewise a pointer of type *char will copy 1 byte. The literal you are using is a shortened form of 0x00000256, those 4 bytes will be copied into memory location starting at &data[1].

2. Endianness

Almost certainly, this operation will assign the following (is this backwards from what you were expecting?): as almost everything in use these days is little endian.

 data[1] = 0x56
 data[2] = 0x2
 data[3] = 0x0
 data[4] = 0x0

3. Alignment

consider the following c++ program (for the alignof operator)

#include <iostream>

using namespace std;

int main(int argc,char *argv[])
{
   char a[4];
   int b[1];

   cout << "char alignment = " << alignof(char) << endl;
   cout << "int alignment = " << alignof(int) << endl;
   cout << "a alignment = " << alignof(a) << endl;
   cout << "b alignment = " << alignof(b) << endl;
}

which produces

char alignment = 1
int alignment = 4
a alignment = 1
b alignment = 4

From the C++ spec (section 3.11)

Object types have alignment requirements (3.9.1, 3.9.2) which place restrictions on the addresses at which an object of that type may be allocated. An alignment is an implementation-defined integer value representing the number of bytes between successive addresses at which a given object can be allocated.

Which means that accessing/storing a type is subject to it's alignment it's up the the implementation to decide what happens when this is violated.

For modern Intel hardware see here, here, and here, your operation will likely work. But accessing mis-aligned data is not guaranteed to be atomic on Intel and it's discouraged. However, on other (Sparc) hardware, you very well may end up with an exception (bus error) when trying to store that value and the program will crash.

Community
  • 1
  • 1
waTeim
  • 9,095
  • 2
  • 37
  • 40