我在函数中使用前向声明时遇到问题。通常在全局范围内,我们可以使用使用extern
关键字声明的未定义变量的地址。看一下这个简单的例子。
typedef struct Id {
int a;
} xIdRec;
typedef xIdRec* IdN;
typedef struct ChId{
int a;
IdN* b;
} ChIdRec;
extern ChIdRec Evn;
IdN Arr[] = {(IdN)&Evn};
ChIdRec Evn = {8, Arr};
但是如何在函数定义期间使用此代码?我们可以尝试这样使用它。
void F (){
typedef struct Id {
int a;
} xIdRec;
typedef xIdRec* IdN;
typedef struct ChId{
int a;
IdN* b;
} ChIdRec;
extern ChIdRec Evn;
IdN Arr[] = {(IdN)&Evn};
ChIdRec Evn = {8, Arr};
}
但现在我们遇到了错误 - error C2086: 'ChIdRec Evn' : redefinition
。
我们可以删除Evn
的第一个声明,但我们会有另一个错误 - error C2065: 'Evn' : undeclared identifier
。
我如何解决这个问题?
答案 0 :(得分:1)
不要重复函数内部类型的定义。特别是typedef
使得这是一个新的标识符,即使它与全局标识符具有相同的名称和含义。
答案 1 :(得分:0)
extern
表示变量在另一个代码单元中定义,由链接器解析。如果结构是在本地函数中定义的,那么我看不出你如何期望它extern
。
问题是你有一个外部变量,然后你试图将同一个变量声明为local。编译器说“下定决心,是外部还是本地?”。
似乎你的前向声明的唯一原因是你可以在结构上使用{ }
初始化语法。最好按成员分配成员而不是使用黑客。
如果你必须那么你就可以使用void *
,但是那些不知不觉中有陷阱。
答案 2 :(得分:0)
extern ChIdRec Evn;
在放入函数时不会按照您的想法执行。
extern
的变量是全局变量。即使你在一个函数内声明它。这可以让您说您在函数体的中间使用extern
全局变量,在您访问它的位置附近。但它确实意味着你不能“转发声明”一个局部变量。
现在,理论上你可以在一个地方创建你的struct
而不构建它,做更多的工作,然后使用C ++ 11中的统一初始化语法就地new
。
即:
ChIdRec Evn;
IdN Arr[] = {(IdN)&Evn};
new(&Evn)ChIdRec{8, Arr};
或类似的东西。 (注意使用placement new
,我没有在免费商店(也就是堆)上创建内存。另请注意,ChIdRec
的双重构造如果不是POD则是危险的 - 如果包含ChIdRec一个std::string
,我希望上面的内容可以泄漏或崩溃,例如。
更荒谬但更正确的方法:
unsigned char EvnBuff[sizeof(ChIdRec)];
IdN Arr[] = {reinterpret_cast<IdN>(&EvnBuff[0])};
new(&EvnBuff[0])ChIdRec{8, Arr};
ChIdRec& Evn = *reinterpret_cast<ChIdRec*>(&EvnBuff[0]);
// ... code goes here
Evn->~ChIdRec (); // before leaving body of function, iff ChIdRec::~ChIdRec exists
可以装扮成花哨的东西,使它异常安全,不那么尴尬。基本上,延迟构造抽象会使这一点略微荒谬。