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

2021-12-31 00:00:00 compiler-errors c++ visual-studio-2013

重要信息:

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

问题:

我在通过 IDE 编译我的静态库项目时收到以下警告:

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.

我相信这行代码与问题有关,这是在我的 Win32 窗口包装类中调用的:

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 是指向我的 Direct3D 包装类的指针.

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.

最后,我要问以下问题:

  1. C4316 是什么意思?
  2. 是什么导致了我的代码?
  3. 如果我忽略它,这对未来会产生什么影响?
  4. 如何修复"导致出现此警告的问题?

附加信息:

当我将 Visual Studio 的配置管理器更改为针对 x64 进行编译时,不会出现此问题.

When I changed Visual Studio's configuration manager to compile for x64, this issue does not occur.

推荐答案

C4316 是什么意思?

What does C4316 mean?

C4316 是错误代码.这是一个唯一标识符,可让您轻松找到文档.

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?

DirectX::XMMATRIX 类的用法.该类的实例必须在 16 字节边界上对齐.编译器确保每当您在堆栈或全局范围内创建 JGLib::Graphics::Direct3D 实例时,它都会正确对齐它,但是如果您在堆上动态分配一个实例,编译器不能保证对象会正确对齐,因为 malloc() 和朋友通常只保证 8 字节对齐.

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?

由于 SSE 指令对未对齐的数据进行操作,您的代码在访问这些矩阵实例时可能会崩溃.

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?

正如文档所建议的,您需要覆盖类的 operator newoperator delete 以保证 16 字节对齐.您可以使用 _aligned_malloc()_aligned_free() 分配和释放在较大对齐上对齐的内存.

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.

相关文章