[C++] warning C4316: l'oggetto allocato sull'heap potrebbe non essere allineato 16


Answers

Devi sostituire i nuovi operatori e eliminarli, in questo modo:

__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);
    }
};
Question

Informazioni importanti:

  • Sistema operativo di sviluppo: Windows 8.1 a 64 bit
  • SO di destinazione: Windows 8.1 a 64 bit
  • IDE: Visual Studio 2013 Professional
  • Lingua: C ++

Il problema:

Ricevo il seguente avviso durante la compilazione del mio progetto di libreria statica tramite l'IDE:

warning C4316: ... : object allocated on the heap may not be aligned 16

Potrei semplicemente ignorare questo avvertimento ... ma presumo che sia lì per una ragione e vorrei almeno capire cosa significa e quali implicazioni potrebbe avere in futuro.

Credo che questa linea di codice sia correlata al problema , che viene chiamato all'interno della mia classe wrapper di finestre Win32:

m_direct3D = new Direct3D(this);

m_direct3D è un puntatore alla mia classe wrapper Direct3D.

Ecco il file di intestazione per il wrapper (ammetto che ha bisogno di ridurre):

#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;
        };
    }
}

Ho provato a cercare su Google il problema, ma ho trovato poche informazioni. Le informazioni che ho trovato non le ho capite.

La conclusione, sto chiedendo il seguente:

  1. Cosa significa "C4316"?
  2. Cosa sta causando nel mio codice?
  3. Quali implicazioni potrebbero avere questo in futuro, se lo ignoro?
  4. Come faccio a "risolvere" il problema che sta causando la visualizzazione di questo avviso?

Informazioni aggiuntive:

Quando ho cambiato il gestore di configurazione di Visual Studio per compilare x64, questo problema non si verifica.




DirectX::XMMATRIX contiene dati SSE (ed è contrassegnato con __declspec(align(16) ) a causa di questo), e pertanto deve essere allineato sul limite 16B, altrimenti le istruzioni che accedono ad esso causeranno una violazione di accesso.

L'avviso indica che non vi è alcuna memoria di garanzia restituita dall'operatore nuovo è allineato 16B.

Puoi invece creare l'oggetto come variabile globale o locale? In questo modo il compilatore può applicare l'allineamento. Se non è possibile, è possibile fornire overloaded new e delete per la classe Direct3D implementata utilizzando _aligned_malloc e _aligned_free .




Links