Can someone show a simple example on c++, which will cause datatype misalignment exception? I want to see an example without using RaiseException function.
-
3Context, please. Standard C++ does not have a "datatype misalignment exception". – Pete Becker Nov 11 '18 at 20:46
-
2Somewhat remarkably, there is no dedicated SEH exception code for it. Reported as a regular AV (0xc0000005) with the read or write address at 0xff...ffff – Hans Passant Nov 12 '18 at 08:52
-
1I don't think you can anymore. The x86 CPUs have always had a fixup, so its a performance issue but not a SEH. When Windows NT still supported various RISC architecture CPUs unaligned access would trigger SEH exceptions. (Itanium, MIPS and so on). – Chris Becke Nov 12 '18 at 10:40
-
[Windows Data Alignment on IPF, x86, and x64](https://msdn.microsoft.com/ru-ru/office/aa290049(v=vs.90)) - *With that said, there are situations on the x86 and x64 platform where unaligned access will generate a general-protection exception. (Note that these are general-protection exceptions, not alignment-check exceptions.)* – RbMm Nov 17 '18 at 00:28
3 Answers
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".

- 61,398
- 6
- 86
- 164
-
1But its will be Access violation exception with code 0xc0000005, but i want to get Datatype Misalignment exception with code 0x80000002 – spartaneg Nov 14 '18 at 00:36
-
1
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.

- 32,904
- 11
- 98
- 167
-
1MSVC doesn't support **inline** assembly in 64-bit mode. But you can still compile an ASM file into object code, and use that. – IInspectable Nov 12 '18 at 09:46
This will not cause an exception but both g++ and clang++ gives an error message about the misalignment. Perhaps VS will too.
#include <iostream>
#include <stdexcept>
struct example {
uint64_t a;
uint64_t b;
};
int main() {
example A;
A.a = 1;
A.b = 2;
example* B = (example*)((char*)&A+1);
try {
std::cout << B->a << "\n";
std::cout << "no exception thrown\n";
} catch(const std::exception& ex) {
std::cout << "exception: " << ex.what() << "\n";
}
}
Example output:
test.cpp:15:25: runtime error: member access within misaligned address 0x7ffd3f7cbe21 for type 'struct example', which requires 8 byte alignment
0x7ffd3f7cbe21: note: pointer points here
00 00 00 01 00 00 00 00 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0f 40 00 00
^
144115188075855872
no exception thrown

- 93,841
- 5
- 60
- 108
-
`(example*)((char*)&A+1)` is undefined behavior. You cannot alias pointers like that. The runtime check is nice, but a conforming implementation is not bound to produce anything that resembles your code. A compiler is allowed to emit code as if you had written `int main() {}`, for example. With that said, on x86 architectures, it's very challenging to produce code that triggers hardware faults on unaligned access. To my knowledge, it only ever happens when using the vector units (SSE, etc.) to read or write data. – IInspectable Nov 12 '18 at 09:38