texto para notas justificar justificado justificacion como comando codigo bloc alinear c++ compiler-errors visual-studio-2013

c++ - para - advertencia C4316: el objeto asignado en el montón puede no estar alineado 16



justificar texto html (4)

¿Qué significa C4316?

C4316 es el código de error. Es un identificador único que facilita la búsqueda de la documentación .

¿Qué está causando en mi código?

El uso de la clase DirectX::XMMATRIX . Las instancias de esa clase deben estar alineadas en los límites de 16 bytes. El compilador se asegura de que cada vez que cree una JGLib::Graphics::Direct3D en la pila o en el alcance global, la alineará correctamente, pero si asigna una instancia dinámicamente en el montón, el compilador no puede garantizar que el el objeto se alineará correctamente, porque malloc() y sus amigos normalmente solo garantizan la alineación de 8 bytes.

¿Qué implicaciones podría tener esto en el futuro, si lo ignoro?

Su código puede bloquearse al acceder a esas instancias de matriz debido a las instrucciones de SSE que operan con datos mal alineados.

¿Cómo "soluciono" el problema que está causando que aparezca esta advertencia?

Como lo sugiere la documentación, debe anular el operator new su clase operator new y operator delete para garantizar la alineación de 16 bytes. Puede usar _aligned_malloc() y _aligned_free() para asignar y liberar memoria alineada en alineaciones más grandes.

Información importante:

  • SO de desarrollo: Windows 8.1 de 64 bits
  • Sistema operativo objetivo: Windows 8.1 de 64 bits
  • IDE: Visual Studio 2013 Professional
  • Idioma: C ++

El problema:

Recibo la siguiente advertencia al compilar mi proyecto de biblioteca estática a través del IDE:

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

Simplemente podría ignorar esta advertencia ... pero supongo que está ahí por algún motivo y me gustaría, al menos, entender qué significa y qué implicaciones podría tener en el futuro.

Creo que esta línea de código está relacionada con el problema , que se llama dentro de mi clase contenedora de ventanas Win32:

m_direct3D = new Direct3D(this);

m_direct3D es un puntero a mi clase de contenedor Direct3D.

Aquí está el archivo de encabezado para el contenedor (admito que necesita recortar):

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

Intenté buscar en Google el problema, pero encontré poca información. La información que encontré no entendí.

La conclusión, estoy preguntando lo siguiente:

  1. ¿Qué significa C4316?
  2. ¿Qué está causando en mi código?
  3. ¿Qué implicaciones podría tener esto en el futuro, si lo ignoro?
  4. ¿Cómo "soluciono" el problema que está causando que aparezca esta advertencia?

Información Adicional:

Cuando cambié el administrador de configuración de Visual Studio para compilar para x64, este problema no ocurre.


Debe anular los operadores nuevos y eliminarlos, así:

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


Si observa el código preprocesado, probablemente encontrará algo como este __declspec(align(16)) allí, solicitando que se alinee a 16 bytes mientras que el new puede no alinearse en esa restricción. Contabilizando en http://msdn.microsoft.com/en-us/library/vstudio/dn448573.aspx puede solucionarlo anulando 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. sobrealineados para 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 contiene datos SSE (y está marcado con __declspec(align(16) ) debido a esto) y, por lo tanto, debe alinearse en el límite 16B; de lo contrario, las instrucciones que acceden a él provocarán una infracción de acceso.

La advertencia le dice que no hay garantía de que la memoria devuelta por el operador nuevo esté alineada 16B.

¿Puedes crear el objeto como una variable global o local en su lugar? De esa manera, el compilador puede hacer cumplir la alineación. Si no puede, puede proporcionar new y delete sobrecargados para su clase Direct3D implementada usando _aligned_malloc y _aligned_free .