警告C4316:堆上分配的对象可能未对齐16

OMG*_*chy 17 c++ compiler-errors visual-studio-2013

重要信息:

  • 开发操作系统:Windows 8.1 64位
  • 目标操作系统:Windows 8.1 64位
  • IDE:Visual Studio 2013 Professional
  • 语言:C++

问题:

通过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)

我试过谷歌搜索问题,但发现的信息很少.我发现的信息我不明白.

结论,我问以下问题:

  1. C4316是什么意思?
  2. 在我的代码中导致它的原因是什么?
  3. 如果我忽视它,将来会有什么影响呢?
  4. 如何"修复"导致出现此警告的问题?

附加信息:

当我将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)


Mar*_*k B 5

如果您查看预处理代码,您可能会__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.


Sum*_*uma 5

DirectX::XMMATRIX包含 SSE 数据(因此用 标记__declspec(align(16)),因此需要在 16B 边界上对齐,否则访问它的指令将导致访问冲突。

该警告告诉您不能保证 operator new 返回的内存是 16B 对齐的。

您可以将对象创建为全局变量或局部变量吗?这样编译器就可以强制对齐。如果不能,您可以使用_aligned_malloc_aligned_free为您的类提供重载new和实现。deleteDirect3D