Viladoman / StructLayout

Visual Studio Extension for C++ struct memory layout visualization
MIT License
477 stars 22 forks source link

[Bug] Using "#pragma once" instead of include guards causes a bunch of redefinition errors when trying to display the layout of a struct inside a header file #40

Closed AndreiDespinoiu closed 1 year ago

AndreiDespinoiu commented 1 year ago

Hello.

I'm using Visual Studio 2019 (Community) v16.11.17, Struct Layout v0.6.3.

The header file in question contains "#pragma once" at the top. It compiles just fine, but I can't use Struct Layout with it. It only works if I replace it with "traditional" include guards like:

#ifndef COMPONENTS_H
#define COMPONENTS_H
// code
#endif

This is the output that I'm getting:

[00:43:11] Capturing configuration from VS projects...
[00:43:11] Looking for structures at c:\projects\learnopengl\LearnOpenGL\src\Components.h:486:12...
[00:43:11] TOOL ARGUMENTS: -r=486 -c=12 -o=c:\users\andrei\appdata\local\microsoft\visualstudio\16.0_e6df47a9\extensions\lycg3s5h.ebv\Generated\tempResult.slbin -p c:\users\andrei\appdata\local\microsoft\visualstudio\16.0_e6df47a9\extensions\lycg3s5h.ebv\Generated\compile_commands c:\projects\learnopengl\LearnOpenGL\src\Components.h
[00:43:11] CLANG ARGUMENTS:  -x c++ -m32 -std=c++17 -w -IC:\Projects\LearnOpenGL\Dependencies\include -IC:\Projects\LearnOpenGL\src\external -working-directory=C:\Projects\LearnOpenGL\LearnOpenGL
c:\projects\learnopengl\LearnOpenGL\src\Components.h:55:8: error: redefinition of 'AiComponent'
struct AiComponent
       ^
c:\projects\learnopengl\LearnOpenGL\src/SceneGraph.h:7:10: note: 'c:\projects\learnopengl\LearnOpenGL\src/Components.h' included multiple times, additional include site here
#include "Components.h"
         ^
c:\projects\learnopengl\LearnOpenGL\src\Components.h:60:8: error: redefinition of 'AudioComponent'
struct AudioComponent
       ^
c:\projects\learnopengl\LearnOpenGL\src/SceneGraph.h:7:10: note: 'c:\projects\learnopengl\LearnOpenGL\src/Components.h' included multiple times, additional include site here
#include "Components.h"
         ^
c:\projects\learnopengl\LearnOpenGL\src\Components.h:72:8: error: redefinition of 'BillboardComponent'
struct BillboardComponent
       ^
c:\projects\learnopengl\LearnOpenGL\src/SceneGraph.h:7:10: note: 'c:\projects\learnopengl\LearnOpenGL\src/Components.h' included multiple times, additional include site here
#include "Components.h"
         ^
c:\projects\learnopengl\LearnOpenGL\src\Components.h:79:8: error: redefinition of 'BoxColliderComponent'
struct BoxColliderComponent
       ^
c:\projects\learnopengl\LearnOpenGL\src/SceneGraph.h:7:10: note: 'c:\projects\learnopengl\LearnOpenGL\src/Components.h' included multiple times, additional include site here
#include "Components.h"
         ^
c:\projects\learnopengl\LearnOpenGL\src\Components.h:86:8: error: redefinition of 'SphereColliderComponent'
struct SphereColliderComponent
       ^
c:\projects\learnopengl\LearnOpenGL\src/SceneGraph.h:7:10: note: 'c:\projects\learnopengl\LearnOpenGL\src/Components.h' included multiple times, additional include site here
#include "Components.h"
         ^
c:\projects\learnopengl\LearnOpenGL\src\Components.h:92:8: error: redefinition of 'CapsuleColliderComponent'
struct CapsuleColliderComponent
       ^
c:\projects\learnopengl\LearnOpenGL\src/SceneGraph.h:7:10: note: 'c:\projects\learnopengl\LearnOpenGL\src/Components.h' included multiple times, additional include site here
#include "Components.h"
         ^
c:\projects\learnopengl\LearnOpenGL\src\Components.h:99:8: error: redefinition of 'ConeColliderComponent'
struct ConeColliderComponent
       ^
c:\projects\learnopengl\LearnOpenGL\src/SceneGraph.h:7:10: note: 'c:\projects\learnopengl\LearnOpenGL\src/Components.h' included multiple times, additional include site here
#include "Components.h"
         ^
c:\projects\learnopengl\LearnOpenGL\src\Components.h:107:8: error: redefinition of 'CylinderColliderComponent'
struct CylinderColliderComponent
       ^
c:\projects\learnopengl\LearnOpenGL\src/SceneGraph.h:7:10: note: 'c:\projects\learnopengl\LearnOpenGL\src/Components.h' included multiple times, additional include site here
#include "Components.h"
         ^
c:\projects\learnopengl\LearnOpenGL\src\Components.h:115:8: error: redefinition of 'CompoundColliderComponent'
struct CompoundColliderComponent
       ^
c:\projects\learnopengl\LearnOpenGL\src/SceneGraph.h:7:10: note: 'c:\projects\learnopengl\LearnOpenGL\src/Components.h' included multiple times, additional include site here
#include "Components.h"
         ^
c:\projects\learnopengl\LearnOpenGL\src\Components.h:121:8: error: redefinition of 'ConvexHullColliderComponent'
struct ConvexHullColliderComponent
       ^
c:\projects\learnopengl\LearnOpenGL\src/SceneGraph.h:7:10: note: 'c:\projects\learnopengl\LearnOpenGL\src/Components.h' included multiple times, additional include site here
#include "Components.h"
         ^
c:\projects\learnopengl\LearnOpenGL\src\Components.h:128:8: error: redefinition of 'TriangleMeshColliderComponent'
struct TriangleMeshColliderComponent
       ^
c:\projects\learnopengl\LearnOpenGL\src/SceneGraph.h:7:10: note: 'c:\projects\learnopengl\LearnOpenGL\src/Components.h' included multiple times, additional include site here
#include "Components.h"
         ^
c:\projects\learnopengl\LearnOpenGL\src\Components.h:134:8: error: redefinition of 'TerrainColliderComponent'
struct TerrainColliderComponent
       ^
c:\projects\learnopengl\LearnOpenGL\src/SceneGraph.h:7:10: note: 'c:\projects\learnopengl\LearnOpenGL\src/Components.h' included multiple times, additional include site here
#include "Components.h"
         ^
c:\projects\learnopengl\LearnOpenGL\src\Components.h:142:8: error: redefinition of 'CameraComponent'
struct CameraComponent
       ^
c:\projects\learnopengl\LearnOpenGL\src/SceneGraph.h:7:10: note: 'c:\projects\learnopengl\LearnOpenGL\src/Components.h' included multiple times, additional include site here
#include "Components.h"
         ^
c:\projects\learnopengl\LearnOpenGL\src\Components.h:154:8: error: redefinition of 'CamShakeComponent'
struct CamShakeComponent
       ^
c:\projects\learnopengl\LearnOpenGL\src/SceneGraph.h:7:10: note: 'c:\projects\learnopengl\LearnOpenGL\src/Components.h' included multiple times, additional include site here
#include "Components.h"
         ^
c:\projects\learnopengl\LearnOpenGL\src\Components.h:177:8: error: redefinition of 'DirectionalLightComponent'
struct DirectionalLightComponent
       ^
c:\projects\learnopengl\LearnOpenGL\src/SceneGraph.h:7:10: note: 'c:\projects\learnopengl\LearnOpenGL\src/Components.h' included multiple times, additional include site here
#include "Components.h"
         ^
c:\projects\learnopengl\LearnOpenGL\src\Components.h:187:8: error: redefinition of 'EnemyComponent'
struct EnemyComponent
       ^
c:\projects\learnopengl\LearnOpenGL\src/SceneGraph.h:7:10: note: 'c:\projects\learnopengl\LearnOpenGL\src/Components.h' included multiple times, additional include site here
#include "Components.h"
         ^
c:\projects\learnopengl\LearnOpenGL\src\Components.h:192:8: error: redefinition of 'HealthComponent'
struct HealthComponent
       ^
c:\projects\learnopengl\LearnOpenGL\src/SceneGraph.h:7:10: note: 'c:\projects\learnopengl\LearnOpenGL\src/Components.h' included multiple times, additional include site here
#include "Components.h"
         ^
c:\projects\learnopengl\LearnOpenGL\src\Components.h:197:8: error: redefinition of 'HealthBarComponent'
struct HealthBarComponent
       ^
c:\projects\learnopengl\LearnOpenGL\src/SceneGraph.h:7:10: note: 'c:\projects\learnopengl\LearnOpenGL\src/Components.h' included multiple times, additional include site here
#include "Components.h"
         ^
c:\projects\learnopengl\LearnOpenGL\src\Components.h:208:8: error: redefinition of 'MeshComponent'
struct MeshComponent
       ^
c:\projects\learnopengl\LearnOpenGL\src/SceneGraph.h:7:10: note: 'c:\projects\learnopengl\LearnOpenGL\src/Components.h' included multiple times, additional include site here
#include "Components.h"
         ^
fatal error: too many errors emitted, stopping now [-ferror-limit=]
20 errors generated.
Error while processing c:\projects\learnopengl\LearnOpenGL\src\Components.h.
[00:43:13] [ERROR] Unable to scan the given location. (2.0141 s)
Viladoman commented 1 year ago

Without having access to the code I would say you have an issue with circular dependencies on the Components.h header file, or the same file in different locations. That might not be exposed during a regular build due to the order of includes in the .cpp files using it.

This is not an issue of the extension but a dependency architecture issue on the include dependency tree that might only arise when parsing a header file directly.

tldr: Components.h depends on Components.h

AndreiDespinoiu commented 1 year ago

Like I said, my project compiles fine, with either "#pragma once" or with include guards. Meanwhile, Struct Layout only works with include guards.

Viladoman commented 1 year ago

I understand that. That doesn't mean that trying to just build a header file directly will work if the dependencies are not properly handled. Struct Layout is just running Clang on your code, so maybe your code only works on MSVC compilers or there is something odd with the compilation from the header. Does struct layout produce the same results from a .cpp file? Implementations details on how pragma once works may vary between compilers. As recommended before, if for some reason clang is not able to consume your code, you can always try the PDB extractor instead.