如何修复这个未声明的标识符? (C++)

Posted

技术标签:

【中文标题】如何修复这个未声明的标识符? (C++)【英文标题】:How do I fix this undeclared identifier? (C++) 【发布时间】:2020-07-23 15:36:14 【问题描述】:

我目前正在用 C++ 编写 VST,但遇到了问题。我已经在网上冲浪和 *** 有一段时间了,但我被卡住了。两个文件给了我这个问题,SynthesizerTwo.hSynthesizerTwo.cpp

我得到的错误是:

'kNumPrograms': undeclared identifier [in SynthesizerTwo.h]

我有一个名为 kNumPrograms 的 const int,它在 SynthesizerTwo.cpp 中声明如下:

#include "SynthesizerTwo.h"

#pragma warning( suppress : 4101 4129 )
#include "IPlug_include_in_plug_src.h"

#include "IControl.h"
#include "resource.h"

const int kNumPrograms = 1; //Original Declaration

enum EParams

    kNumParams
;

然后,在SynthesizerTwo.h 中,在SynthesizerTwo 类中使用如下:

#ifndef __SYNTHESIZERTWO__
#define __SYNTHESIZERTWO__

#include "Oscillator.h"
#include "MIDIReceiver.h"

#pragma warning( suppress : 4101 4129 )
#include "IPlug_include_in_plug_hdr.h"

class SynthesizerTwo : public IPlug


public:

  SynthesizerTwo(IPlugInstanceInfo instanceInfo);
  ~SynthesizerTwo();
  //const int kNumPrograms = 5;
  void Reset();
  void OnParamChange(int paramIdx);
  void ProcessDoubleReplacing(double** inputs, double** outputs, int nFrames);

  // to receive MIDI messages:
  void ProcessMidiMsg(IMidiMsg* pMsg);

private:
  double mFrequency;
  void SynthesizerTwo::CreatePresets() 
      
      MakeDefaultPreset((char*)"-", kNumPrograms); //This is what gives me the error
  
  Oscillator mOscillator;

  MIDIReceiver mMIDIReceiver;
;

#endif

我尝试将声明放入 .h 文件,但随后出现 LNK2019 链接器错误。我还尝试在 .cpp..h 的声明之前使用 extern

我尝试将声明放在类之外的.h、公共部分和私有部分。我还尝试将 .cpp 中的声明移到 .h #include 上方,但仍然出现错误。

链接器错误:

Severity    Code    Description Project File    Line    Suppression State
Error   LNK2019 unresolved external symbol "public: void __thiscall MIDIReceiver::advance(void)" (?advance@MIDIReceiver@@QAEXXZ) referenced in function "public: virtual void __thiscall SynthesizerTwo::ProcessDoubleReplacing(double * *,double * *,int)" (?ProcessDoubleReplacing@SynthesizerTwo@@UAEXPAPAN0H@Z) SynthesizerTwo-vst2 C:\wdl-ol\IPlugExamples\SynthesizerTwo\SynthesizerTwo.obj   1   

任何帮助将不胜感激。

【问题讨论】:

void SynthesizerTwo::CreatePresets() 应该是 void CreatePresets()。将该函数的实现移动到.cpp 文件中(在kNumPrograms 的声明之后)。 无关:你为什么要投射 (char*)"-" 而不是只调用 MakeDefaultPreset("-", kNumPrograms); 谢谢,我试试看。 不相关:由于您链接到的框架已存档,并且它们链接到新框架iPlug2,也许您最好从它开始? 是的,我决定将框架切换到 iPlug2。感谢您的帮助! 【参考方案1】:

这是您的 SynthesizerTwo.cpp 文件在预处理器包含文件后的样子,其中大部分被删除:

class SynthesizerTwo : public IPlug

...
  double mFrequency;
  void SynthesizerTwo::CreatePresets() 
      
      MakeDefaultPreset((char*)"-", kNumPrograms); //This is what gives me the error
  
...

const int kNumPrograms = 1; //Original Declaration

如您所见,kNumPrograms 在声明之前使用。事后声明也无济于事。此外,如果您将“SynthesizerTwo.h”包含在任何其他文件中,则根本不会有声明。

解决方案:在使用之前声明变量。

但问题是,我尝试在 .h 和 .h 的 #include 上方的 .cpp 中声明它。如 OP 中所述,它给了我链接器错误。

如果您在标头中定义命名空间范围变量,则应将其声明为inline


#define __SYNTHESIZERTWO__

您已经定义了一个为语言实现保留的标识符。因此,您的程序的行为是未定义的(如果它首先编译的话)。您应该使用另一个标头保护。

(char*)"-"

这似乎很危险。避免抛弃 constness。

【讨论】:

为了澄清第二个问题:其中带有__ 的名称是为编译器保留的。所以也许有一天你在一个自己定义__SYNTHESIZERTWO__的编译器上编译它,然后你的头文件突然不起作用。 但问题是,我尝试在.h.h#include 上方的.cpp 中声明它。如 OP 中所述,它给了我链接器错误。 另外,我正在使用一个框架,__ 也随之而来。 @OboeWanKenobi 好吧,现在您知道框架附带的示例已损坏。 @OboeWanKenobi 它已在所有标准版本的 C 和 C++ 中被破坏。如果它是在 1989 年之前编写的(C 的标准化),那么我想这个例子可以原谅(但可能是时候将 30 年前的例子更新为现代标准了)。 worked for a ton of people for years. 那就是行为未定义的事情。只是看起来有效并不意味着它有效。明天可能会突然停止工作。【参考方案2】:

一种可能的解决方案是将extern const int kNumPrograms; 放在类之前的标题中。

extern 将作为前向声明,问题将得到解决。

例如:

#include <iostream>
//this act like a forward decleration (in your header)
extern const int kNumPrograms;
void f()

    std::cout<< kNumPrograms <<std::endl;



//real decleration come after (in your cpp)
const int kNumPrograms = 1;

int main()

    f();
    return 0;

【讨论】:

我不确定如何使其可重现,因为除了 SynthesizerTwo.h 无法访问 kNumPrograms 之外,我不确定究竟是什么导致了问题。

以上是关于如何修复这个未声明的标识符? (C++)的主要内容,如果未能解决你的问题,请参考以下文章

修复“错误 C2065:未声明的标识符”

C++ 类实例标识符未声明

未声明 Visual c++ 标识符

我在 Visual Studio C++ 中遇到这些错误:“NuovoUtente”:未声明的标识符和“CercareUtente”:未声明的标识符 [关闭]

C++ 编程错误 |未声明的标识符

C++ 对象未声明标识符