Approved syntax for handling raw pointer

I am doing the procedure of copying a block of memory and have to deal with blocks of raw memory in efficient pieces. My question is not about the specialized copy procedure that I create, but about how to properly examine the alignment of the source pointer in C.

I have a raw memory pointer, let's say it is already represented as a non-zero char *. In my architecture, I can very efficiently copy memory in 64 byte chunks, WHEN THIS IS CONFIRMED to a block of 64 bytes in size. So the (standard) trick is that I will make a simple copy of 0-63 bytes "manually" in the head and / or tail to convert the copy from an arbitrary char * of arbitrary length to a 64-byte aligned pointer with a multiple of 64 bytes in length.

Now the question arises: how do you legally "check" a pointer to the definition (and manipulation) of its alignment? The obvious way is to include it in an integer and just check the bits:

char *pointer=something. int p=(int)pointer; char *alignedPointer=(char *)((p+63)&~63); 

Please note that here I understand that alignedPointer does not point to the same memory as the pointer ... it is a rounded pointer to which I can call my efficient copy procedure and I will process any other bytes to the beginning manually.

But compilers (justifiably) cause a craze when entering a pointer into an integer. But how else can I examine and manipulate the lower bits of a pointer in LEGAL C? Ideally, with different compilers, I would not receive any errors or warnings.

+6
c pointers bit-manipulation alignment portability
source share
4 answers

For integer types large enough to hold pointers, C99 stdint.h has:

For data lengths:

that were around long before the C99.

If your platform does not have this data, you can maximize code portability while still using these type names and the appropriate typedef for them.

+7
source share

I don’t think that in the past people were also reluctant to make their own beat-knocks, but maybe the current ones don’t touch that β€œthe mood will help someone to create some kind of standard library for aligning pointers, If you do not have an official api, you have no choice but to AND and OR, or your path.

+1
source share

Instead of int, try a data type that should be the same size as the pointer (INT_PTR on Win32 / 64). Maybe the compiler will not be too worried. :) Or use the union if 64-bit compatibility is not important.

0
source share

Pointing pointers to and from integers are valid, but the results are determined by implementation. See Section 6.3.2.3 of the standard. Apparently, the intention is that the results are what people familiar with the system would expect, and in fact this usually happens in practice.

If the architecture in question can efficiently manipulate pointers and integers, and the only problem is whether it will work on all compilers for this system, then the answer is that it will probably be anyway.

(Of course, if I were to write this code, I would think that this is normal, since it has not been proved otherwise. My experience is that the compilers for this system all behave in very similar ways at this level, the assembler language just offers a specific the approach everyone takes.)

"Probably works" is not very good general advice, though, so my suggestion is to simply write code that works, just round off its #ifdef so that it can only be compiled by a well-known compiler and deferred to memcpy in other cases.

#ifdef rarely perfect, but it's pretty lightweight compared to other features. And if compiler-specific behaviors or tricks are required, parameters are still limited.

0
source share

All Articles