Important Information:
The Problem:
I get the following warning when compiling my static library project through the IDE:
warning C4316: ... : object allocated on the heap may not be aligned 16
I could simply ignore this warning...but I'm assuming it's there for a reason and would like to at least understand what it means and what implications it could have in the future.
I believe this line of code is related to the problem, which is called inside my Win32 window wrapper class:
m_direct3D = new Direct3D(this);
m_direct3D is a pointer to my Direct3D wrapper class.
Here is the header file for the wrapper (I admit it needs trimming down):
#pragma once
// Windows
#include <d3d11.h>
#include <DirectXMath.h>
// Standard
#include <stdint.h>
#include <vector>
// JGlib
#include "Window.h"
namespace JGlib
{
namespace Graphics
{
class Direct3D
{
public:
// Construtor and destructor
Direct3D(const JGlib::Graphics::Window* window);
~Direct3D();
// Public methods
void Initialise();
void BeginDraw();
void Draw();
void EndDraw();
private:
// Private methods
// Private member variables
const Window* m_window;
ID3D11Device* m_device;
IDXGIAdapter* m_adapter;
DXGI_ADAPTER_DESC m_adapterDescription;
uint32_t m_videoCardMemory;
IDXGIFactory* m_factory;
IDXGIOutput* m_monitor;
DXGI_MODE_DESC* m_displayModes;
uint32_t m_numberOfModes;
DXGI_RATIONAL m_refreshRate;
DXGI_SWAP_CHAIN_DESC m_swapChainDescription;
D3D_FEATURE_LEVEL m_featureLevel;
ID3D11DeviceContext* m_deviceContext;
IDXGISwapChain* m_swapChain;
ID3D11Texture2D* m_backBuffer;
ID3D11RenderTargetView* m_renderTargetView;
ID3D11Texture2D* m_depthStencilBuffer;
D3D11_TEXTURE2D_DESC m_depthBufferDescription;
D3D11_DEPTH_STENCIL_DESC m_depthStencilDescription;
ID3D11DepthStencilState* m_depthStencilState;
ID3D11DepthStencilView* m_depthStencilView;
D3D11_RASTERIZER_DESC m_rasterDescription;
D3D11_VIEWPORT m_viewport;
float m_fieldOfView;
float m_screenAspectRatio;
ID3D11RasterizerState* m_rasterState;
DirectX::XMMATRIX m_projectionMatrix;
DirectX::XMMATRIX m_worldMatrix;
DirectX::XMMATRIX m_orthographicMatrix;
float m_screenDepth;
float m_screenNear;
};
}
}
I tried googling the issue, but found little information. The information I did find I did not understand.
The conclude, I am asking the following:
Additional Information:
When I changed Visual Studio's configuration manager to compile for x64, this issue does not occur.
What does C4316 mean?
C4316 is the error code. It's a unique identifier that makes it easy to find the documentation.
What is causing it in my code?
The usage of the DirectX::XMMATRIX
class. Instances of that class must be aligned on 16-byte boundaries. The compiler makes sure that whenever you create a JGLib::Graphics::Direct3D
instance on the stack or at global scope, it will align it properly, but if you allocate an instance dynamically on the heap, the compiler can't guarantee that the object will be aligned properly, because malloc()
and friends typically only guarantee 8-byte alignment.
What implications could this have in the future, if I ignore it?
Your code may crash when accessing those matrix instances due to SSE instructions operating on misaligned data.
How do I "fix" the problem that is causing this warning to appear?
As the documentation suggests, you need to override your class's operator new
and operator delete
in order to guarantee 16-byte alignment. You can use _aligned_malloc()
and _aligned_free()
to allocate and free memory aligned on larger alignments.
You need to override the new and delete operators, like this:
__declspec(align(16)) class MyClass
{
public:
DirectX::XMMATRIX m_projectionMatrix;
virtual ~MyClass()
{
}
void* operator new(size_t i)
{
return _mm_malloc(i,16);
}
void operator delete(void* p)
{
_mm_free(p);
}
};
If you look at the pre-processed code you'll probably find something like this __declspec(align(16))
in there, requesting to be aligned at 16 bytes while new
may not align at that constraint. Accoding to http://msdn.microsoft.com/en-us/library/vstudio/dn448573.aspx you can fix it by Override operator new and operator delete for over-aligned types so that they use the aligned allocation routines—for example, _aligned_malloc and _aligned_free.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With