我有一个用C ++ 11重写的旧C代码。在较早的C代码(这是一个控制台应用程序)struct
中,TC.C文件中的全局变量为。有问题的结构是
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代码这struct
是不初始化并用于如下
#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
intgLoc
中的值时
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 *
现在,我将代码从C应用程序移到了C ++ 11应用程序。代码可以正常运行,但是tgLoc
调用的值CreateCodeTable
现在是
tgLoc Grouper:
+ m_szTabName 0xcdcdcdcd <Error reading characters of string.> char *
+ m_szCWName 0xcdcdcdcd <Error reading characters of string.> char *
+ m_fpCWFile 0xcdcdcdcd {_ptr=??? _cnt=??? _base=??? ...} _iobuf *
+ m_dNatCost 0xcdcdcdcd {???} double *
+ m_dStateCost 0xcdcdcdcd {???} double *
+ m_dLocalCost 0xcdcdcdcd {???} double *
m_nDateRanges -12851 short
m_sNumCodes -12851 short
+ m_gStart 0xcdcdcdcd {???} long *
+ m_gEnd 0xcdcdcdcd {???} long *
+ m_sIcdVsn 0xcdcdcdcd {???} short *
+ m_sIcdEdn 0xcdcdcdcd {???} short *
+ m_tIcdMap 0xcdcdcdcd {???} MapRecord * *
+ m_tHdr {m_sCreateDate=0x27570cc0 "ÍÍÍÍÍÍ... m_usRefID=52685 m_cHiByte=-51 'Í' ...} FileHeader
+ m_tDxTab {m_ucCodeLen=205 'Í' m_usNumHdr=52685 m_usNumCodes=52685 ...} CodeHeader
+ m_tPrTab {m_ucCodeLen=205 'Í' m_usNumHdr=52685 m_usNumCodes=52685 ...} CodeHeader
+ m_tCCMatTab {m_ucNRow=205 'Í' m_ucNCol=205 'Í' m_cpCCMatrix=0xcdcdcdcd <Error reading characters of string.> } CCMatrixHeader
+ m_tNeoTab {m_usNumCodes=52685 m_ucNeoVal=0xcdcdcdcd <Error reading characters of string.> } NeoHeader
+ m_tDRGTab {m_usNumDRG=52685 m_usNumBits=52685 m_bBitVals=0xcdcdcdcd {???} ...} DRGHeader
+ m_tCCTab {m_usNumCodes=52685 m_ucSep=0xcdcdcdcd <Error reading characters of string.> m_useCCRow=0xcdcdcdcd {...} } CCHeader
+ m_tCCExclTab {m_usNumCCHdr=52685 m_usNumCCTail=52685 m_usLowPDX=0xcdcdcdcd {???} ...} CCExclHeader
+ m_tLogic {wFldErr=52685 wDefLen=52685 wFldLen=52685 ...} LogicHeader
+ m_tCodeRec 0xcdcdcdcd {szCode=0xcdcdcdcd <Error reading characters of string.> ucFldNum=??? ucFldType=??? ...} CodeRecord *
+ m_szLabStore 0xcdcdcdcd <Error reading characters of string.> char *
调用之前只有一小段代码,CreateCodeTable
并且不会初始化tgLoc
,所以我的问题是,为什么在C ++ 11下编译的新代码与旧版C代码的初始化方式不同,如何初始化新代码,所以这tgLoc
包含的旧代码,它首先使用相同的价值观?
我知道这0xCDCDCDCD
是来自C运行时库的调试值。在调试版本中分配内存块时,会将其初始化为该虚假值,以期捕获错误。0xCDCDCDCD
为非NULL,并且永远不是有效的内存指针。但这似乎正在影响该CreateCodeTable
方法的输出。我还不明白为什么将其编译为C ++ 11时会像C一样初始化此值? 参考
谢谢你的时间。
因此,Grouper tgLoc不会被初始化
是的。它是一个全局的,因此被初始化为0,这是您可以看到的。根据C 99标准草案6.7.8:
10)如果具有自动存储期限的对象未明确初始化,则其值不确定。如果未明确初始化具有静态存储持续时间的对象,则:
- 如果具有指针类型,则将其初始化为空指针;
- 如果具有算术类型,则将其初始化为(正数或无符号)零;
- 如果是聚合,则根据这些规则(递归)初始化每个成员;
- 如果是联合,则根据这些规则初始化(递归)第一个命名成员。
在第6.2节中详细说明了确定“静态存储持续时间”的规则,在这种情况下为6.2.4.3,“使用外部或内部链接或使用存储类说明符static声明其标识符的对象具有静态存储持续时间”。
没有关键字static
(也称为全局)的文件作用域标识符具有外部链接。
我已将代码从C应用程序移至C ++ 11应用程序。该代码运行正常,但是现在调用CreateCodeTable时tgLoc的值是
最有可能是因为现在它实际上尚未初始化,因此包含操作系统提供的伪垃圾(或真正的垃圾,由RAM提供,或您引用的调试值)。这意味着它不再是全局的(局部变量没有链接,因此没有“自动存储持续时间”,因此不会隐式初始化-这适用于C和C ++)。无论如何,您可以使用以下方法将其初始化为0:
Grouper tgLoc = { 0 };
这适用于所有成员,而不仅仅是第一个。在C ++中,就= { }
可以了。
万一这还不清楚:如果您想要一个全为零的结构,则必须像在第一种情况下那样,以显式或隐式的方式对其进行初始化。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句