Can someone show a simple example on c++, which will cause datatype misalignment exception? I want to see an example without using RaiseException function.
Datatype misalignment exception win32 example
1.4k Views Asked by spartaneg AtThere are 3 best solutions below
On
This has become harder with recent versions of MSVC, because they no longer honour the aligned intrinsics such as _mm_load_ps or _mm_store_ps, they get compiled as if you asked for the unaligned versions. But streaming loads only have an aligned version, so we can use that here to force it to fail on an unaligned address. For example like this:
__m128i test()
{
char buffer[17];
__m128i a = _mm_stream_load_si128((__m128i*)buffer);
__m128i b = _mm_stream_load_si128((__m128i*)(buffer + 1));
return _mm_or_si128(a, b);
}
There are two loads that are 1 byte apart, the address cannot be aligned both times, so it fails. The actual exception would present as "Access violation reading location 0xFFFFFFFF".
On
I want to see an example without using RaiseException function.
Without who using the RaiseException function? Someone has to...because the only way you're going to get an exception catchable by a C++ construct (be that __try of SEH or try of C++ exceptions) is if something somewhere raises it.
At a hardware level, the x86 processor has an Alignment Check (AC) flag. If the flag is set then interrupt 17 is executed when an unaligned access occurs. But with Windows, you can only hook such an interrupt if you are in kernel mode.
If you wanted a usermode C++ program to receive exceptions related to unaligned accesses--originating from the processor's innate ability to observe unaligned access, you'd have to write that in a device driver. And even then, getting an exception would involve some callback to usermode which led to raising it.
Just for the heck of it to see if I could cause crashes of some kind on bad alignments, I tried adapting some inline assembly from this answer into MSVC. (MSVC's syntax is different, but I gather this should do it... at least doing a subsequent pushfd and examining it with extracted local variables suggested the AC bit does get changed by the process):
#include <iostream>
int main() {
__asm {
pushfd
mov eax, [esp]
or eax, 0x40000
mov [esp], eax
popfd
}
char *data = new char[sizeof(int) + 1];
int *p = reinterpret_cast<int*>(data + 1);
*p = 304;
std::cout << *p;
}
But it doesn't appear to trigger any new errors. I can't read the cr0 register to see if alignment mask is set, it won't let me (mov eax, cr0 causes a "privileged instruction" error). And I don't know what Windows puts to respond to interrupt 17 by default, maybe a no-op? Or it's likely that x86 programs on a 64-bit build of Windows don't heed any of this, but I can't do the 64-bit instruction because MSVC doesn't support inline assembly in 64-bit. :-/
Regardless, point remains: for your Win32 C++ program to be notified via exception of an alignment error, something has to tell it...and Windows isn't configured to reacting to alignment problems noticed by the processor itself. So all your notifications are going to be coming from things like compiler warnings or usermode added runtime checks on pointer values themselves.
This will not cause an exception but both g++ and clang++ gives an error message about the misalignment. Perhaps VS will too.
Example output: