OMG*_*chy 17 c++ compiler-errors visual-studio-2013
重要信息:
问题:
通过IDE编译我的静态库项目时收到以下警告:
warning C4316: ... : object allocated on the heap may not be aligned 16
Run Code Online (Sandbox Code Playgroud)
我可以简单地忽略这个警告......但我认为这是有原因的,并且至少要了解它意味着什么以及它将来会产生什么影响.
我相信这行代码与问题有关,在我的Win32窗口包装类中调用它:
m_direct3D = new Direct3D(this);
Run Code Online (Sandbox Code Playgroud)
m_direct3D是指向我的Direct3D包装类的指针.
这是包装器的头文件(我承认它需要修剪):
#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;
};
}
}
Run Code Online (Sandbox Code Playgroud)
我试过谷歌搜索问题,但发现的信息很少.我发现的信息我不明白.
结论,我问以下问题:
附加信息:
当我将Visual Studio的配置管理器更改为x64编译时,不会发生此问题.
Ada*_*eld 27
C4316是什么意思?
C4316是错误代码.它是一个唯一的标识符,可以轻松找到文档.
在我的代码中导致它的原因是什么?
DirectX::XMMATRIX
该类的用法.该类的实例必须在16字节边界上对齐.编译器确保无论何时JGLib::Graphics::Direct3D
在堆栈或全局范围内创建实例,它都会正确对齐它,但如果在堆上动态分配实例,则编译器无法保证对象将正确对齐,因为malloc()
和朋友通常只保证8字节对齐.
如果我忽视它,将来会有什么影响呢?
由于SSE指令在未对齐的数据上运行,因此在访问这些矩阵实例时,您的代码可能会崩溃.
如何"修复"导致出现此警告的问题?
正如文档所示,您需要覆盖您的类operator new
,operator delete
以保证16字节对齐.您可以使用_aligned_malloc()
和_aligned_free()
分配和释放在较大路线上对齐的内存.
agu*_*iva 17
您需要覆盖new和delete运算符,如下所示:
__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);
}
};
Run Code Online (Sandbox Code Playgroud)
如果您查看预处理代码,您可能会__declspec(align(16))
在其中找到类似的内容,请求在 16 字节处对齐,而new
可能不会在该约束处对齐。根据http://msdn.microsoft.com/en-us/library/vstudio/dn448573.aspx,您可以通过以下方式修复它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.
DirectX::XMMATRIX
包含 SSE 数据(因此用 标记__declspec(align(16)
),因此需要在 16B 边界上对齐,否则访问它的指令将导致访问冲突。
该警告告诉您不能保证 operator new 返回的内存是 16B 对齐的。
您可以将对象创建为全局变量或局部变量吗?这样编译器就可以强制对齐。如果不能,您可以使用_aligned_malloc和_aligned_free为您的类提供重载new
和实现。delete
Direct3D