2014-07-09 20 views
2

我有一箇舊的C代碼,我在C++ 11中重寫。在較舊的C代碼(它是一個控制檯應用程序)中有一個struct,它是文件TC.C中的一個全局變量;有問題的結構是C代碼和它的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值在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 * 

現在,我已經移動從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之前的代碼只有一小amound,這確實初始化tgLoc,所以我的問題是爲什麼在C++ 11下編譯的新代碼與舊C代碼的初始化方式不同,我如何初始化新代碼以使tgLoc包含與第一次使用的舊代碼相同的值?

我知道0xCDCDCDCD是一個調試值,它來自C運行時庫。當您在調試版本中分配一塊內存時,它將被初始化爲這個虛假值,以便捕捉錯誤。 0xCDCDCDCD是非NULL並且永遠不是有效的內存指針。但是這似乎影響了CreateCodeTable方法的輸出。我也不明白爲什麼這個值被初始化爲C,當它被編譯爲C++ 11時?Reference

謝謝你的時間。

+0

在你的C++ 11版本中,在你的'Grouper'結構中聲明'std :: string m_szTabName;'這樣的字符串字段。另外,用'g ++ -std = C++編譯11 -Wall -Wextra -g' –

+0

在大多數地方我正在做這個翻譯('char *' - >'std :: string'),但是我繼承的代碼是大規模的。我試圖保持這樣的結構(這是大量使用)不觸摸,以避免過多的重寫... – MoonKnight

+0

@BasileStarynkevitch -Wextra選項給出了一個'錯誤錯誤D8021:無效的數值參數'/ Wextra'... '在VS2013錯誤。 – MoonKnight

回答

5

所以石斑魚tgLoc不會被初始化

是的。這是一個全球性的,因此被初始化爲0,這是你可以看到的。從C 99標準草案6.7.8:

10)如果具有自動存儲持續時間的對象沒有被明確初始化,它的值是 不確定的。如果具有靜態存儲持續時間對象未初始化明確, 然後:

  • 如果它有指針類型,它被初始化爲空指針;
  • 如果它有算術類型,它被初始化爲(正或無符號)零;
  • 如果它是一個聚合,每個成員根據這些規則初始化(遞歸);
  • 如果它是一個聯合,則根據這些 規則初始化(遞歸)第一個命名成員。

確定什麼「靜態存儲持續時間」的規則是在6.2節中闡明,在此情況下6.2.4.3「,其標識符與外部或內部聯動或與 聲明一個目的存儲級說明符static 的靜態存儲時間爲「。

的文件範圍標識符而不關鍵字static(亦稱,全局)具有外部聯動。

我已將代碼從C應用程序移至C++ 11應用程序。該代碼運行正常,但tgLoc的在呼叫到CreateCodeTable值是現在

最有可能的,因爲現在它真的初始化,所以包含由操作系統提供僞垃圾(或真正的垃圾,提供來自RAM,或者您引用的調試值)。這意味着它不再是一個全局變量(本地變量沒有鏈接,因此「自動存儲時間」,所以不會被隱式初始化 - 這適用於C和C++)。在任何情況下,你可以初始化爲0,即:

Grouper tgLoc = { 0 }; 

這適用於所有成員國,不只是第一個。在C++中,只有= { }沒問題。

如果不清楚:如果你想要一個滿零的結構,它必須以這種方式初始化,或者明確地或者隱式地,如第一種情況。

+0

非常感謝您的時間。當我說初始化 - 我的意思是明確的;正如你後來繼續澄清。我會再測試一次,再次感謝。 – MoonKnight

+1

我發現C標準中的一些段落,如果有任何疑問,請添加這些段落。 – delicateLatticeworkFever

+1

「*在C++ 11下,只是'= {}'很好。*」在C++的任何修訂版本中都不錯,不僅僅是C++ 11。 : - ] – ildjarn