Strict Pointer Aliasing Question

B

Bryan Parkoff

I create one 32 Bits variable and four pointer variables. Four pointer
variables link or point to one 32 Bits variable. Each pointer variable is 8
Bits. Look at my example below.

unsigned int AA = 0;
unsigned char* const AA_Byte1 = (unsigned char*)&AA;
unsigned char* const AA_Byte2 = (unsigned char*)&AA + 1;
unsigned char* const AA_Byte3 = (unsigned char*)&AA + 2;
unsigned char* const AA_Byte4 = (unsigned char*)&AA + 3;

AA = 0x41424344;
printf("First Byte: %Xh", *AA_Byte1);
printf("Second Byte: %Xh", *AA_Byte2);
printf("Third Byte: %Xh", *AA_Byte3);
printf("Fourth Byte: %Xh", *AA_Byte4);
printf("Native DWord: %Xh", AA);

My style above works fine for my own coding. I don't need to use SHIFT,
AND, OR, or other keywords because it may slow on Pentium 4. For example
below.

unsigned char A = 0x01;
unsigned char B = 0x20;
unsigned int C = (B << 8 | A) & 0xffff;

I am not sure if my style coding will work on other processors
(non-Intel and non-AMD like Big/Little Endian). I don't use union because
it is not efficiency, but I would prefer to leave one variable at 32 Bits or
64 Bits. I use pointer alaising to point one 32 Bits / 64 Bits variable
will benefit great.

Please explain what Strict Pointer Aliasing rule mean because I am told
that it will not work at high optimization on other processors, but it runs
fine on any Intel and AMD processor family.

It is necessary to place CONST between "unsigned char*" and "AA_Byte1"
because I don't want the pointer address to be modified. One problem is
that I can't do in C++ class because it is not designed at initialization.
I tried to use static outside of C++ class, but it does not work that way.
Can you please give the hint how to overcome the problem? I can only be
able to place static const before unsigned char*, but can't do between
unsigned char* and variable name in C++ class. There has to be another way
to prevent pointer address to be modified.

I am told that C++ class is much better than global object because it
can remain in stack segment, but global object can remain in data segment
(Intel / AMD arch). I understand that store objects in stack segment is
much faster than data segment. Is it true?

Why do many C programmers want to avoid using C++ class while they use
struct object in global object? It won't be very efficency. Please explain
what you think that I should stay with C++ class. Thanks...
 
R

Ron Natalie

You can access any object as an array of unsigned char (read the first few paragrahs of
3.9). The only thing not portable versus the shifting and oring is that the ordering
of the four bytes in the int (or the fact that sizeof (int) is 4 for that matter) may differ.

In your case AA_Byte1 might be the least significant bits (no shift) ...which it is
on little-endian machines like the Intel. Or it might be the most significant bits
(shift << 24) like on the Sun.
I am not sure if my style coding will work on other processors
(non-Intel and non-AMD like Big/Little Endian). I don't use union because
it is not efficiency, but I would prefer to leave one variable at 32 Bits or
64 Bits. I use pointer alaising to point one 32 Bits / 64 Bits variable
will benefit great.

What's not efficient about unions?
Please explain what Strict Pointer Aliasing rule mean because I am told
that it will not work at high optimization on other processors, but it runs
fine on any Intel and AMD processor family.

Strict aliasing means that the compiler can make assumptions about what kind
of poitners can access what things. For example, there's no guarantee that
if you used two unsigned short*'s above (rather than 4 char's), that they would
retrieve the values you wanted.

Strict aliasing doesn't preclude using char types to access the object. Other
types are not.
It is necessary to place CONST between "unsigned char*" and "AA_Byte1"
because I don't want the pointer address to be modified. One problem is
that I can't do in C++ class because it is not designed at initialization.

What you wrote should be fine C++. That is initialization.
I tried to use static outside of C++ class, but it does not work that way.

What way?
Can you please give the hint how to overcome the problem? I can only be
able to place static const before unsigned char*, but can't do between
unsigned char* and variable name in C++ class. There has to be another way
to prevent pointer address to be modified.

I'm confused. What you work is fine. What problem are you observing?
I am told that C++ class is much better than global object because it
can remain in stack segment, but global object can remain in data segment
(Intel / AMD arch). I understand that store objects in stack segment is
much faster than data segment. Is it true?

No, you have a bunch of unfounded assumptions. First, a C++ class can
be a global object or a static object or a dynamic object. Object type and.
storage are independent concepts. Furtther access speed rarely differs
much between the different storage types.
 
T

tom_usenet

I create one 32 Bits variable and four pointer variables. Four pointer
variables link or point to one 32 Bits variable. Each pointer variable is 8
Bits. Look at my example below.

unsigned int AA = 0;
unsigned char* const AA_Byte1 = (unsigned char*)&AA;
unsigned char* const AA_Byte2 = (unsigned char*)&AA + 1;
unsigned char* const AA_Byte3 = (unsigned char*)&AA + 2;
unsigned char* const AA_Byte4 = (unsigned char*)&AA + 3;

AA = 0x41424344;
printf("First Byte: %Xh", *AA_Byte1);
printf("Second Byte: %Xh", *AA_Byte2);
printf("Third Byte: %Xh", *AA_Byte3);
printf("Fourth Byte: %Xh", *AA_Byte4);
printf("Native DWord: %Xh", AA);

Does that really faster code than:

unsigned int AA = 0;
unsigned char* const AA_Byte1 = (unsigned char*)&AA;

AA = 0x41424344;
printf("First Byte: %Xh", AA_Byte1[0]);
printf("Second Byte: %Xh", AA_Byte1[1]);
printf("Third Byte: %Xh", AA_Byte1[2]);
printf("Fourth Byte: %Xh", AA_Byte1[3]);
printf("Native DWord: %Xh", AA);
(or even use a loop above)

? Have you either timed the code or examined the assembler?
My style above works fine for my own coding. I don't need to use SHIFT,
AND, OR, or other keywords because it may slow on Pentium 4. For example
below.

unsigned char A = 0x01;
unsigned char B = 0x20;
unsigned int C = (B << 8 | A) & 0xffff;

I am not sure if my style coding will work on other processors
(non-Intel and non-AMD like Big/Little Endian).

Well, the bytes will come in a different order of course. Whether this
affects your program depends on whether you depend on a particular
byte order.

I don't use union because
it is not efficiency, but I would prefer to leave one variable at 32 Bits or
64 Bits. I use pointer alaising to point one 32 Bits / 64 Bits variable
will benefit great.

A union should be as efficient as the alternative version I've
suggested. But is this code really so time critical? And does your
optimizer really do such a bad job?
Please explain what Strict Pointer Aliasing rule mean because I am told
that it will not work at high optimization on other processors, but it runs
fine on any Intel and AMD processor family.

If it doesn't work, then the compiler is buggy.
It is necessary to place CONST between "unsigned char*" and "AA_Byte1"
because I don't want the pointer address to be modified. One problem is
that I can't do in C++ class because it is not designed at initialization.
I tried to use static outside of C++ class, but it does not work that way.
Can you please give the hint how to overcome the problem? I can only be
able to place static const before unsigned char*, but can't do between
unsigned char* and variable name in C++ class. There has to be another way
to prevent pointer address to be modified.

You can have const members in classes, but you must initialize them in
the initializer list of the constructor. e.g.

myclass::myclass(DWORD* p)
:p1(reinterpret_cast<unsigned char*>(p)), p2(p1 + 1), p3(p1 + 2),
p4(p1 + 3)
{
}

assuming p1 is declared:
unsigned char* p1 const;
I am told that C++ class is much better than global object because it
can remain in stack segment, but global object can remain in data segment
(Intel / AMD arch). I understand that store objects in stack segment is
much faster than data segment. Is it true?

I suggest you test it, or ask in an architecture specific group.
Certainly on some architectures stack variables are faster than
globals.
Why do many C programmers want to avoid using C++ class while they use
struct object in global object? It won't be very efficency. Please explain
what you think that I should stay with C++ class. Thanks...

There is no point in optimizing something if doing so makes no
difference to the perceivable or measurable speed of an application.
Profile before optimization, and only optimize at all if your code is
too slow.

Tom

C++ FAQ: http://www.parashift.com/c++-faq-lite/
C FAQ: http://www.eskimo.com/~scs/C-faq/top.html
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,995
Messages
2,570,230
Members
46,817
Latest member
DicWeils

Latest Threads

Top