C代码和it C++;翻译初始化不同
我有一个旧的C代码,我正在用C++11重写。在旧的C代码中(它是一个控制台应用程序),在TC.C文件中有一个作为全局变量的C代码和it C++;翻译初始化不同,c,c++11,initialization,C,C++11,Initialization,我有一个旧的C代码,我正在用C++11重写。在旧的C代码中(它是一个控制台应用程序),在TC.C文件中有一个作为全局变量的struct;所讨论的结构是 typedef struct { char* m_szTabName; char* m_szCWName; FILE* m_fpCWFile; double* m_dNatCost; double* m_dStateCost;
struct
;所讨论的结构是
typedef struct
{
char* m_szTabName;
char* m_szCWName;
FILE* m_fpCWFile;
double* m_dNatCost;
double* m_dStateCost;
double* m_dLocalCost;
short m_nDateRanges;
short m_sNumCodes;
GTIME* m_gStart;
GTIME* m_gEnd;
short* m_sIcdVsn;
short* m_sIcdEdn;
MapRecord** m_tIcdMap;
FileHeader m_tHdr;
CodeHeader m_tDxTab;
CodeHeader m_tPrTab;
CCMatrixHeader m_tCCMatTab;
NeoHeader m_tNeoTab;
DRGHeader m_tDRGTab;
CCHeader m_tCCTab;
CCExclHeader m_tCCExclTab;
LogicHeader m_tLogic;
CodeRecord* m_tCodeRec;
char* m_szLabStore;
} Grouper;
在C代码中,此结构未初始化,使用方法如下
#include "tabcomp.h"
#include "OtherHeaderFiles"
...
Grouper tgLoc;
...
void main(int argc, char *argv[])
{
FILE *fpOut, *fpIn;
...
CreateCodeTable(fpIn, &tgLoc.m_tDxTab, (int)DX_LAB);
...
}
因此,Grouper tgLoc
不会被初始化,在调用CreateCodeTable
时,tgLoc
中的值是
tgLoc Grouper:
+ m_szTabName 0x00000000 <NULL> char *
+ m_szCWName 0x00000000 <NULL> char *
+ m_fpCWFile 0x00000000 <NULL> _iobuf *
+ m_dNatCost 0x00000000 {???} double *
+ m_dStateCost 0x00000000 {???} double *
+ m_dLocalCost 0x00000000 {???} double *
+ m_nDateRanges 0 short
+ m_sNumCodes 0 short
+ m_gStart 0x00000000 {???} long *
+ m_gEnd 0x00000000 {???} long *
+ m_sIcdVsn 0x00000000 {???} short *
+ m_sIcdEdn 0x00000000 {???} short *
+ m_tIcdMap 0x00000000 {???} TMapRec * *
+ m_tHdr {m_sCreateDate=0x00e80150 "" m_usRefID=0 m_cHiByte=0 '\0' ...} FileHeader
+ m_tDxTab {m_ucCodeLen=0 '\0' m_usNumHdr=0 m_usNumCodes=0 ...} CodeHeader
+ m_tPrTab {m_ucCodeLen=0 '\0' m_usNumHdr=0 m_usNumCodes=0 ...} CodeHeader
+ m_tCCMatTab {m_ucNRow=0 '\0' m_ucNCol=0 '\0' m_cpCCMatrix=0x00000000 <NULL> } CCMatrixHeader
+ m_tNeoTab {m_usNumCodes=0 m_ucNeoVal=0x00000000 <NULL> } TNeoHdr
+ m_tDRGTab {m_usNumDRG=0 m_usNumBits=0 m_bBitVals=0x00000000 {???} ...} DRGHeader
+ m_tCCTab {m_usNumCodes=0 m_ucSep=0x00000000 <NULL> m_useCCRow=0x00000000 {???} } CCHeader
+ m_tCCExclTab {m_usNumCCHdr=0 m_usNumCCTail=0 m_usLowPDX=0x00000000 {???} ...} CCExclHeader
+ m_tLogic {wFldErr=0 wDefLen=0 wFldLen=0 ...} LogicHeader
+ m_tCodeRec 0x00000000 <NULL> CodeRecord *
+ m_szLabStore 0x00000000 <NULL> char *
在调用CreateCodeTable
之前只有少量代码,而这不会初始化tgLoc
,因此我的问题是,为什么在C++11下编译的新代码的初始化方式与旧的C代码不同?我如何初始化新代码,使tgLoc
包含的值与第一次使用的旧代码相同
我知道0xcdcdcd
是一个来自C运行时库内部的调试值。当您在调试构建中分配内存块时,它被初始化为这个伪值,以期捕获bug0xCDCDCDCD
为非空,并且永远不是有效的内存指针。但这似乎影响了CreateCodeTable
方法的输出。我也不明白为什么这个值在编译为C++11时会像C一样初始化
谢谢你抽出时间
所以石斑鱼tgLoc没有初始化
是的。它是一个全局变量,因此初始化为0,这是您可以看到的。根据C 99标准草案6.7.8:
10) 如果没有显式初始化具有自动存储持续时间的对象,则其值为
不确定的如果没有显式初始化具有静态存储持续时间的对象,
然后:
- 如果有指针类型,则初始化为空指针李>
- 如果它有算术类型,则初始化为(正或无符号)零李>
- 如果是聚合,则根据这些规则(递归地)初始化每个成员李>
- 如果它是一个联合,那么第一个命名成员将根据以下规则(递归)初始化 规则
static
(又称全局)的文件作用域标识符具有外部链接
我已经将代码从C应用程序移到了C++11应用程序。代码运行正常,但调用CreateCodeTable时的tgLoc值现在为
很可能是因为现在它还没有初始化,所以包含了操作系统提供的伪垃圾(或者是真正的垃圾,由RAM提供,或者是您提到的调试值)。这意味着它不再是全局变量(局部变量没有链接,因此“自动存储持续时间”,因此不会隐式初始化——这在C和C++中都适用)。在任何情况下,都可以使用以下命令初始化为0:
Grouper tgLoc = { 0 };
这适用于所有成员,而不仅仅是第一个成员。在C++中,只是<代码> = {} /COD>是好的。< /P>
如果这一点不清楚:如果您想要一个满是零的结构,那么必须像第一种情况那样显式或隐式地初始化它。在您的C++11版本中,声明字符串字段,如
std::string m_szTabName代码>在您的Grouper
结构中。另外,使用g++-std=c++11-Wall-Wextra-g
编译,我在大多数地方都在做这个翻译(char*
->std::string
),但我继承的代码是大量的。我试图保持这样的结构(大量使用)不变,以避免过度重写…@BasileStarynkevitch-Wextra选项在VS2013中给出了一个错误1错误D8021:invalid numeric argument'/Wextra'.
错误。我建议使用。使用最新版本(至少4.8)。非常感谢您的时间。当我说初始化-我的意思是明确的;正如你稍后继续澄清的那样。我会再次测试这个,再次感谢。我发现了C标准的一些段落,并添加了一些疑义。“在C++ 11下,只是代码> {{} /CODE>”是很好的。“在C++的任何修订中,这不太好,不只是C++ 11。
Grouper tgLoc = { 0 };