尽管有一次编译指示,VS2012 仍抱怨“已定义”类

Posted

技术标签:

【中文标题】尽管有一次编译指示,VS2012 仍抱怨“已定义”类【英文标题】:VS2012 complaining about "already defined" classes despite pragma once 【发布时间】:2013-12-06 10:18:31 【问题描述】:

我的项目有点困惑。语言是 C++,编辑器 Visual Studio 2012,一旦完成,它应该是一个光线投射渲染器(光线投射位仍然缺失)。 为此,我正在使用数学库 Eigen。但是,当我尝试构建时出现链接错误。过去我很少使用 C++ 语言,对这个错误所做的研究对我没有帮助。

这是编译器的输出:

1>------ Build started: Project: TX52-3DStereo-RT-CUDA, Configuration: Debug x64 ------
1>Build started 06/12/2013 10:55:56.
1>InitializeBuildStatus:
1>  Touching "x64\Debug\TX52-3DStereo-RT-CUDA.unsuccessfulbuild".
1>AddCudaCompilePropsDeps:
1>Skipping target "AddCudaCompilePropsDeps" because all output files are up-to-date with respect to the input files.
1>CudaBuild:
1>  Compiling CUDA source file kernel.cu...
1>  
1>  C:\Users\Satanikas\Documents\Visual Studio 2012\Projects\TX52-3DStereo-RT-CUDA\TX52-3DStereo-RT-CUDA>"C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v5.5\bin\nvcc.exe" -gencode=arch=compute_10,code=\"sm_10,compute_10\" --use-local-env --cl-version 2012 -ccbin "C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\bin\x86_amd64"  -I"C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v5.5\include" -I"C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v5.5\include"  -G   --keep-dir x64\Debug -maxrregcount=0  --machine 64 --compile -cudart static  -g   -DWIN64 -D_DEBUG -D_CONSOLE -D_MBCS -Xcompiler "/EHsc /W3 /nologo /Od /Zi /RTC1 /MDd  " -o x64\Debug\kernel.cu.obj "C:\Users\Satanikas\Documents\Visual Studio 2012\Projects\TX52-3DStereo-RT-CUDA\TX52-3DStereo-RT-CUDA\kernel.cu" 
1>c:\users\satanikas\documents\visual studio 2012\common\inc\eigen\src/Core/arch/SSE/PacketMath.h(169): warning : controlling expression is constant
1>  
1>c:\users\satanikas\documents\visual studio 2012\common\inc\eigen\src/Core/Block.h(102): error : "operator=" has already been declared in the current scope
1>            detected during instantiation of class "Eigen::Block<XprType, BlockRows, BlockCols, InnerPanel> [with XprType=VectorType, BlockRows=<expression>, BlockCols=<expression>, InnerPanel=false]" 
1>  c:\users\satanikas\documents\visual studio 2012\common\inc\eigen\src/Core/VectorBlock.h(58): here
1>  
1>c:\users\satanikas\documents\visual studio 2012\common\inc\eigen\src/Core/Ref.h(122): error : "operator=" has already been declared in the current scope
1>            detected during instantiation of class "Eigen::RefBase<Derived> [with Derived=Eigen::Ref<PlainObjectType, Options, StrideType>]" 
1>  (183): here
1>  
1>c:\users\satanikas\documents\visual studio 2012\common\inc\eigen\src/Core/products/Parallelizer.h(20): warning : variable "m_maxThreads" was set but never used
1>  
1>c:\users\satanikas\documents\visual studio 2012\common\inc\eigen\src/Geometry/RotationBase.h(76): error : function template "Eigen::operator*(const Eigen::EigenBase<OtherDerived> &, const Eigen::Quaternion<_Scalar, _Options> &)" has already been defined
1>            detected during:
1>              instantiation of class "Eigen::RotationBase<Derived, _Dim> [with Derived=Eigen::Quaternion<_Scalar, _Options>, _Dim=3]" 
1>  c:\users\satanikas\documents\visual studio 2012\common\inc\eigen\src/Geometry/Quaternion.h(35): here
1>              instantiation of class "Eigen::QuaternionBase<Derived> [with Derived=Eigen::Quaternion<_Scalar, _Options>]" 
1>  c:\users\satanikas\documents\visual studio 2012\common\inc\eigen\src/Geometry/Quaternion.h(236): here
1>  
1>  3 errors detected in the compilation of "C:/Users/SATANI~1/AppData/Local/Temp/tmpxft_000010c8_00000000-5_kernel.cpp1.ii".
1>C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\V110\BuildCustomizations\CUDA 5.5.targets(592,9): error MSB3721: The command ""C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v5.5\bin\nvcc.exe" -gencode=arch=compute_10,code=\"sm_10,compute_10\" --use-local-env --cl-version 2012 -ccbin "C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\bin\x86_amd64"  -I"C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v5.5\include" -I"C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v5.5\include"  -G   --keep-dir x64\Debug -maxrregcount=0  --machine 64 --compile -cudart static  -g   -DWIN64 -D_DEBUG -D_CONSOLE -D_MBCS -Xcompiler "/EHsc /W3 /nologo /Od /Zi /RTC1 /MDd  " -o x64\Debug\kernel.cu.obj "C:\Users\Satanikas\Documents\Visual Studio 2012\Projects\TX52-3DStereo-RT-CUDA\TX52-3DStereo-RT-CUDA\kernel.cu"" exited with code 2.
1>
1>Build FAILED.
1>
1>Time Elapsed 00:00:03.40
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

错误来自 3 个类,这里​​是它们的标题:

#pragma once

#include <Eigen\Geometry>

class TransformedObject

public:
    TransformedObject(void);
    ~TransformedObject(void);

    void rotate(const Eigen::Quaternionf&);
    void setRotation(const Eigen::Quaternionf&);
    void translate(const Eigen::Vector3f&);
    void setTranslation(const Eigen::Vector3f&);
    void scale(const float&);
    const Eigen::Matrix4f getMatrix(void);

    Eigen::Transform<float, 3, Eigen::Affine> transform;
;


#pragma once

#include "TransformedObject.h"

class Camera

public:
    Camera(void);
    ~Camera(void);
    void computeRays();
    void setFOV(float angle);
    void setResolution(int w, int h);
private:
    TransformedObject transformation;
    float fov;
    unsigned int width;
    unsigned int height;
    float* raysDirections;
    Eigen::Vector3f raysOrigin;
;


#pragma once

#include <forward_list>
#include "TransformedObject.h"

class ScenegraphNode

public:
    ScenegraphNode(void);
    ~ScenegraphNode(void);
private:
    TransformedObject transformation;
    size_t sceneHash;
    std::forward_list<ScenegraphNode*> children;

    int countVertices() const;
;

如你所见,所有类都有“pragma once”,而Eigen类都被ifndef/define/endif保护。

我收集到的是,这可能是由于我的代码是由不同的 TU 编译的,其中包括单独的 Eigen,因此所有“已定义”错误。但我不知道如何纠正这个问题(我不能使用 extern,因为我使用我的类 TransformedObject 作为其他类的成员)。

提前致谢,

【问题讨论】:

错误完全在 Eigen 标头中,这确实暗示了故障存在。编译时可能需要设置一些配置选项。 Eigen 中对 CUDA 的支持仅在 devel 分支中可用,目前已知只有 nvcc/gcc 对有效。不过欢迎修复 nvcc/msvc。 然后将非cuda代码放入.cpp文件中。 问题解决了,我从包含声明相机的主机函数的文件中删除了所有 CUDA 代码。 (这是一个测试功能)。这意味着它确实是 NVCC 的问题。 您可以发布解决方案作为答案吗?并关闭这张票,这样当我搜索“未回答”的问题时,我就不会得到一堆已经解决的问题? 【参考方案1】:

复制user3073879(提交者)评论:

问题解决了,我从包含声明相机的主机函数的文件中删除了所有 CUDA 代码。(这是一个测试函数)。这意味着它确实是 NVCC 的问题

将此问题标记为已回答。

【讨论】:

以上是关于尽管有一次编译指示,VS2012 仍抱怨“已定义”类的主要内容,如果未能解决你的问题,请参考以下文章

ATL抱怨VS2012后不包括Windows -> VS2017

VS2013 忽略编译指示警告禁用

尽管注释掉了所需的头文件,为啥这个 C++ 程序仍能编译和运行? [复制]

尽管使用 htmlspecialchars 对单引号进行编码,JavaScript 仍然抱怨这些引号需要在函数调用中转义

for 循环上的多个编译指示指令(C 和 VS 2013)

尽管 -isystem 仍生成警告