Unaligned Pointers in C++

Started by
1 comment, last by SeanMiddleditch 9 years, 3 months ago

Hi,

I'm having trouble understanding how to go about defining unaligned pointers. The reason I need them is that they are suggested for the ID3DXFileData::Lock method, to be used as the data buffer.

http://msdn.microsoft.com/en-us/library/windows/desktop/bb205845(v=vs.85).aspx

I read a bit online that there's the __packed qualifier, but when I tried using it, it came up undefined. Can someone point me in the right direction? Maybe I just don't understand alignment and am looking for a quick and easy solution where there is none.

Advertisement
The suggestion of using unaligned pointers is more "read it in as bytes and parse it into the correct type, instead of casting it straight to the datatype you believe it to be."

i.e.
char * dataPtr;
size_t length = FileLength;

fileData->Lock(&length, reinterpret_cast<void**>(&dataPtr));

unsigned signature = *reinterpret_cast<unsigned *>(dataPtr); // BAD! Assumes dataPtr has the same alignment as unsigned.

std::string data(dataPtr, length);
std::istringstream mb(data);

mb.read(reinterpret_cast<char*>(&signature), sizeof(unsigned)); // GOOD! Makes no assumptions about the alignment requirements of dataPtr and unsigned types.

In time the project grows, the ignorance of its devs it shows, with many a convoluted function, it plunges into deep compunction, the price of failure is high, Washu's mirth is nigh.

I'm having trouble understanding how to go about defining unaligned pointers.


foo UNALIGNED* ptr = nullptr;

file->Lock(size, &ptr);
UNALIGNED is a windows.h macro that expands to __unaligned (a Microsoft extension). Since this whole operation you're using is pretty Windows-specific, it shouldn't matter if you're being platform-specific with the unaligned stuff here, but don't get into the habit of leaking this stuff into any public interfaces or platform-neutral code.

For similar cases, you have other options. memcpy can, for some data structures, get the job done here. memcpy makes no alignment assumptions so it can copy to/from an unaligned chunk of bytes to an aligned POD object. It may be faster or slower than unaligned accesses depending on the CPU architecture you're compiling for, but it will pretty much always be faster than parsing a file into an object if the file doesn't otherwise require parsing anyway.


Since this is all just for ID3DXFile which is part of an old, out-dated, obsolete version of D3D, you might consider just dropping all use of D3DX (it doesn't exist anymore on newer SDKs or for newer versions of D3D) and use a library like Open Assert Import Library to load your model files. That gives you a more forward-compatible API and lets you load for more than just .x files.

Sean Middleditch – Game Systems Engineer – Join my team!

This topic is closed to new replies.

Advertisement