
èšäºã®åã®çããŠã©ãŒã ã¢ãããšããŠãèªè
ã«æ¬¡ã®è³ªåãããŠããããããšæããŸããåçå®¶ã¯ãé«å質ã®ç»åãåŸãããã«ã«ã¡ã©ãã©ã®ããã«æ©èœããããç¥ãå¿
èŠããããŸããïŒ ãŸããå°ãªããšã圌ã¯ããã€ã€ãã©ã ãã®æŠå¿µãç¥ã£ãŠããå¿
èŠããããŸããïŒ ä¿¡å·å¯Ÿé鳿¯ïŒ ã被åçæ·±åºŠãïŒ å®è·µã§ã¯ããã®ãããªè€éãªåèªãç¥ã£ãŠããŠãã0.3ã¡ã¬ãã¯ã»ã«ã®ããŒã¿ãéããŠæºåž¯é»è©±ã§ç¹ã«è¯ãæ®ããªãæããææã¡ãã®ãã®ã®ã·ã§ããã¯åçãæ®ãããšãã§ãããšç€ºåããŠããŸãã ãããŠéã«ãçŽ æã®å®å
šãªç¡ç¥ã§ã®çµéšãšã€ã³ã¹ãã¬ãŒã·ã§ã³ã ãã§æ¬åœã«è¯ãåçãåŸãããšãã§ããŸãïŒããã¯ã«ãŒã«ã®äŸå€ã§ãããããã§ããŸã ã§ãïŒã ããããæè¡ãããã¹ãŠãçµãåºãããšãæãå°éå®¶ïŒããã³ããããªãã¯ã¹ã®1å¹³æ¹ããªã¡ãŒãã«ãããã®ã¡ã¬ãã¯ã»ã«æ°ã ãã§ãªãïŒãæ±ããå°éå®¶ã«ãšã£ãŠããã®ç¥èã¯å¿
ãå¿
èŠãšãªããšèª°ããç§ãšäž»åŒµããããšã¯ãŸããããŸãããèš±å¯ãããŠããŸããã ãããŠãããã¯ããžã¿ã«åçæ¥çã ãã§ãªããä»ã®ã»ãšãã©ã®äŒæ¥ã«ãåœãŠã¯ãŸããŸãã
ããã¯ããã°ã©ãã³ã°ã«ãåœãŠã¯ãŸããC ++ã§ã®ããã°ã©ãã³ã°ã«ãåœãŠã¯ãŸããŸãã ãã®èšäºã§ã¯ãã»ãšãã©ãã¹ãŠã®è€éãªã¯ã©ã¹ã«ååšãããä»®æ³ããŒãã«ã€ã³ããã¯ã¹ããšåŒã°ããèšèªã®éèŠãªæŠå¿µãšãããã誀ã£ãŠç Žæããå¯èœæ§ãããæ¹æ³ã«ã€ããŠèª¬æããŸãã ããã«ããããããã°ãšã©ãŒãçºçãã«ãããªããŸãã æåã«ããããäœã§ããããæãåºããæ¬¡ã«ããã«ã©ã®ããã«ããããŠäœãå£ãããã«ã€ããŠã®ç§ã®èããå
±æããŸãã
æ®å¿µãªããšã«ããã®èšäºã§ã¯ãäœã¬ãã«ã«é¢é£ããå€ãã®è°è«ããããŸãã ããããæ®å¿µãªããããã¯ãåé¡ã説æããŠããŸããã åæã«ã64ãããããã°ã©ã ã®ãã«ãã¢ãŒãã§Visual C ++ã³ã³ãã€ã©ã³ã³ãã€ã©ã®å€§éšåã«ã€ããŠèšäºãæžãããããšãäºçŽããŸããä»ã®ã³ã³ãã€ã©ãšç°ãªãã¢ãŒããã¯ãã£ã®ããã°ã©ã ã®çµæã¯ç°ãªãå ŽåããããŸãã
ä»®æ³ããŒãã«ãã€ã³ã¿ãŒ
çè«ã«ããã°ãvptrãã€ã³ã¿ãŒïŒä»®æ³ã¡ãœããã®ããŒãã«ãžã®ãã€ã³ã¿ãŒããŸãã¯ä»®æ³ããŒãã«ãã€ã³ã¿ãŒïŒã¯ãå°ãªããšã1ã€ã®ä»®æ³ã¡ãœãããæã€ãã¹ãŠã®ã¯ã©ã¹ã«ååšããŸãã ã©ããªåç©ãªã®ãã詳ããèŠãŠãããŸãã ãããè¡ãã«ã¯ãC ++ã§ç°¡åãªãã¢ããã°ã©ã ãäœæããŸãã
#include <iostream> #include <iomanip> using namespace std; int nop() { static int nop_x; return ++nop_x; // , ! }; class A { public: unsigned long long content_A; A(void) : content_A(0xAAAAAAAAAAAAAAAAull) { cout << "++ A has been constructed" << endl;}; ~A(void) { cout << "-- A has been destructed" << endl;}; void function(void) { nop(); }; }; void PrintMemory(const unsigned char memory[], const char label[] = "contents") { cout << "Memory " << label << ": " << endl; for (size_t i = 0; i < 4; i++) { for (size_t j = 0; j < 8; j++) cout << setw(2) << setfill('0') << uppercase << hex << static_cast<int> (memory[i * 8 + j]) << " "; cout << endl; } } int main() { unsigned char memory[32]; memset(memory, 0x11, 32 * sizeof(unsigned char)); PrintMemory(memory, "before placement new"); new (memory) A; PrintMemory(memory, "after placement new"); reinterpret_cast<A *>(memory)->~A(); system("pause"); return 0; };
æ¯èŒç倧éã®ã³ãŒãããããŸããããã®åäœã®ããžãã¯ã¯ããªãæçœãªã¯ãã§ãã32ãã€ããã¹ã¿ãã¯ã«å²ãåœãŠããã0x11ã®å€ã§åããããŸãïŒããã¯ã¡ã¢ãªå
ã®ãã¬ããŒãžããšèŠãªãããŸãïŒã 次ã«ããããã®32ãã€ãã®äžã«ã
é
眮newæŒç®åã䜿çšããŠããªãåçŽãªã¯ã©ã¹Aãªããžã§ã¯ããäœæãããæåŸã«ã¡ã¢ãªã®å
容ãåºåããããã®åŸãããã°ã©ã ã¯ãªããžã§ã¯ããç Žæ£ããŠå®è¡ãå®äºããŸãã 以äžã¯ããã®ããã°ã©ã ã®åºåã§ãïŒMicrosoft Visual Studio 2012ãx64ïŒã
Memory before placement new: 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 ++ A has been constructed Memory after placement new: AA AA AA AA AA AA AA AA 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 -- A has been destructed Press any key to continue . . .
ã¡ã¢ãªå
ã®ã¯ã©ã¹ã®ãµã€ãºã¯8ãã€ãã§ãããå¯äžã®ã¡ã³ããŒã§ããunsigned long long content_Aã®ãµã€ãºã«çããããšã¯ç°¡åã«ããããŸãã
ä»®æ³é¢æ°ãvoid颿°ïŒvoidïŒé¢æ°ã®å®£èšã«è¿œå ããŠãããã°ã©ã ãå°ãè€éã«ããŸãããã
virtual void function(void) {nop();};
ããã°ã©ã åºåïŒä»¥äžã§ã¯ãæ°èŠé
眮åã«ã¡ã¢ãªãé€ããŠåºåã®äžéšã®ã¿ã衚瀺ãããä»»æã®ããŒãæŒããŸã...ïŒïŒ
++ A has been constructed Memory after placement new: F8 D1 C4 3F 01 00 00 00 AA AA AA AA AA AA AA AA 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 -- A has been destructed
ç¹°ãè¿ãã«ãªããŸãããã¡ã¢ãªå
ã®ã¯ã©ã¹ãµã€ãºã16ãã€ãã«ãªã£ãããšã¯ç°¡åã«ããããŸãã æåã®8ãã€ãã¯ãä»®æ³ã¡ãœããã®ããŒãã«ãžã®ãã€ã³ã¿ãŒã§å ããããŠããŸãã ããã°ã©ã ã®ãã®éå§æã®ãã€ã³ã¿ãŒã¯0x000000013FC4D1F8ã§ããïŒIntel64ã¯ãªãã«ãšã³ãã£ã¢ã³ã®
ãã€ãé ã䜿çšããŠããããããã€ã³ã¿ãŒãšcontent_Aã¯ã¡ã¢ãªå
ã§ãæ¡åŒµããããŸãããcontent_Aã®å Žåãããã«èšãããšã¯ã§ããŸããïŒã
ä»®æ³ã¡ãœããããŒãã«ã¯ãä»®æ³ã¡ãœãããžã®ãã€ã³ã¿ãŒããªã¹ããããèªåçã«çæãããã¡ã¢ãªå
ã®ç¹å¥ãªæ§é ã§ãã functionïŒïŒã¡ãœããããã¯ã©ã¹Aãžã®ãã€ã³ã¿ãŒã«é¢ããŠã³ãŒãã®ã©ããã§åŒã³åºãããå ŽåãA :: functionïŒïŒé¢æ°ãçŽæ¥åŒã³åºã代ããã«ãç®çã®ãªãã»ããã§ä»®æ³ã¡ãœããã®ããŒãã«ã«ãã颿°ãåŒã³åºãããŸã-ãã®åäœã¯ããªã¢ãŒãã£ãºã ãå®è£
ããŸãã ä»®æ³é¢æ°ããŒãã«èªäœã以äžã«ç€ºããŸãïŒ/ FAsã¹ã€ããã䜿çšããŠã³ã³ãã€ã«ããããšã§ååŸããŸããããã«ãã¢ã»ã³ãã©ã³ãŒãå
ã®é¢æ°ã®ããå¥åŠãªååã«æ³šæããŠãã ãããã
ååã®ãã³ã°ãªã³ã° ããééããŸããïŒã
CONST SEGMENT ??_7A@@6B@ DQ FLAT:??_R4A@@6B@ ; A::'vftable' DQ FLAT:?function@A@@UEAAXXZ CONST ENDS
__declspecïŒnovtableïŒ
ååãšããŠãä»®æ³ã¯ã©ã¹ããŒãã«ãäžèŠãªå ŽåããããŸãã ã¯ã©ã¹Aãã€ã³ã¹ã¿ã³ã¹åããªããšä»®å®ããŸããã€ã³ã¹ã¿ã³ã¹åããå Žåã¯ã鱿«ãšç¥æ¥ã®ã¿ã«ãåæã«1ã€ã®ä»®æ³é¢æ°ãåŒã³åºãããªãããã«æ³šæããŠãã ããã ããã¯ãæœè±¡ã¯ã©ã¹ã®å Žåã«ã¯ããªãäžè¬çãªç¶æ³ã§ããã¯ã©ã¹ãæœè±¡ã¯ã©ã¹ã®å Žåãã€ã³ã¹ã¿ã³ã¹åã§ããªãããšãããã£ãŠããŸãã ãŸããã å®éã颿°ïŒvoidïŒé¢æ°ãæœè±¡ãšããŠã¯ã©ã¹Aã§å®£èšãããå Žåãä»®æ³ã¡ãœããã®ããŒãã«ã¯æ¬¡ã®ããã«ãªããŸãã
CONST SEGMENT ??_7A@@6B@ DQ FLAT:??_R4A@@6B@ ; A::'vftable' DQ FLAT:_purecall CONST ENDS
æããã«ããã®ãããªé¢æ°ãåŒã³åºãããšãããšãèªåã®è¶³ã®è
°çã«ãªããŸãã
質åãçºçããŸãïŒã¯ã©ã¹ãã€ã³ã¹ã¿ã³ã¹åãããªãå Žåããªãä»®æ³ããŒãã«ãã€ã³ã¿ãŒãèšå®ããã®ã§ããïŒ ã³ã³ãã€ã©ãäœåãªã³ãŒããçæããªãããã«ããããã«ã__ declspecïŒnovtableïŒã®åœ¢åŒã§åœä»€ãäžããããšãã§ããŸãïŒæ³šæïŒãã€ã¯ããœããåºæïŒïŒã __declspecïŒnovtableïŒå±æ§ã䜿çšããŠãä»®æ³é¢æ°ã§ãµã³ãã«ã¯ã©ã¹ãæžãçŽããŸãã
class __declspec(novtable) A { .... }
ããã°ã©ã ã®åºåã¯æ¬¡ã®ããã«ãªããŸãã
++ A has been constructed Memory after placement new: 11 11 11 11 11 11 11 11 AA AA AA AA AA AA AA AA 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 -- A has been destructed
ãŸãããªããžã§ã¯ãã®ãµã€ãºã倿ŽãããŠããªããšããäºå®ã«æ³šæããŠãã ãããããã§ã16ãã€ããå¿
èŠãšããŸãã åèšãããšã__ declspecïŒnovtableïŒå±æ§ãå°å
¥ããåŸã2ã€ã®çžéç¹ã®ã¿ãçŸããŸããããŸããä»®æ³ã¡ãœããããŒãã«ã®ã¢ãã¬ã¹ã以åã«ãã£ãå Žæã«ãåæåãããŠããªãã¡ã¢ãªé åããããŸãã 第äºã«-ã¢ã»ã³ãã©ã³ãŒãã§ã¯ãã¯ã©ã¹Aã®ä»®æ³ã¡ãœããã®ããŒãã«ã¯ããååšããŸããã ãã ããä»®æ³ããŒãã«ãã€ã³ã¿ãŒã¯ãŸã ååšãã8ãã€ãã®ãéãããæ®ã£ãŠããŸãã ããã¯èŠããŠããå¿
èŠããããŸã...
ç¶æ¿
ä»®æ³ããŒãã«ãã€ã³ã¿ãŒã䜿çšããŠæœè±¡ã¯ã©ã¹ããæãåçŽãªç¶æ¿ãå®è£
ããããã«äŸãæžãæããŸãã
class __declspec(novtable) A // { public: unsigned long long content_A; A(void) : content_A(0xAAAAAAAAAAAAAAAAull) { cout << "++ A has been constructed" << endl;}; ~A(void) { cout << "-- A has been destructed" << endl;}; virtual void function(void) = 0; }; class B : public A
ãŸããã¯ã©ã¹Aã®ä»£ããã«ãã¡ã€ã³ããã°ã©ã ã§ã¯ã©ã¹BãäœæïŒããã³ç Žæ£ïŒãããããã«ããŸãã
.... new (memory) B; PrintMemory(memory, "after placement new"); reinterpret_cast<B *>(memory)->~B(); ....
ããã°ã©ã ã®åºåã¯æ¬¡ã®ããã«ãªããŸãã
++ A has been constructed ++ B has been constructed Memory after placement new: D8 CA 2C 3F 01 00 00 00 AA AA AA AA AA AA AA AA BB BB BB BB BB BB BB BB 11 11 11 11 11 11 11 11 -- B has been destructed -- A has been destructed
äœãèµ·ãã£ãããææ¡ããŠã¿ãŸãããã ã³ã³ã¹ãã©ã¯ã¿ãŒB :: BïŒïŒãåŒã³åºãããŸããã ãã®ã³ã³ã¹ãã©ã¯ã¿ãŒã¯ãå®è¡ãããåã«ãåºæ¬ã¯ã©ã¹ã®ã³ã³ã¹ãã©ã¯ã¿ãŒã§ããã³ã³ã¹ãã©ã¯ã¿ãŒA :: AïŒïŒãåŒã³åºããŸãã ãŸããä»®æ³ããŒãã«ãã€ã³ã¿ãŒãåæåããå¿
èŠããããŸããã__ declspecïŒnovtableïŒå±æ§ã®ãããåæåãããŸããã§ããã æ¬¡ã«ãã³ã³ã¹ãã©ã¯ã¿ãŒã¯content_Aãã£ãŒã«ãã®å€ã0xAAAAAAAAAAAAAAAAAullïŒã¡ã¢ãªã®2çªç®ã®ãã£ãŒã«ãïŒã«èšå®ããã³ã³ã¹ãã©ã¯ã¿ãŒB :: BïŒïŒã«å¶åŸ¡ãè¿ããŸãã
ãªããžã§ã¯ãBã«ã¯__declspecïŒnovtableïŒå±æ§ããªããããã³ã³ã¹ãã©ã¯ã¿ãŒã¯ä»®æ³ããŒãã«ãã€ã³ã¿ãŒïŒã¡ã¢ãªå
ã®æåã®ãã£ãŒã«ãïŒãã¯ã©ã¹Bä»®æ³ã¡ãœããããŒãã«ã«èšå®ããæ¬¡ã«content_Bã0xBBBBBBBBBBBBBBBBBullïŒã¡ã¢ãªå
ã®3çªç®ã®ãã£ãŒã«ãïŒã«èšå®ããã¡ã€ã³ããã°ã©ã ã«å¶åŸ¡ãè¿ããŸãã ã¡ã¢ãªã®å
容ãããã¯ã©ã¹Bã®ãªããžã§ã¯ããæ£ããæ§ç¯ãããããšãç°¡åã«çè§£ã§ãããã®ã³ã³ããã¹ãã§ã¯äžèŠãªæäœãã¹ããããããããšã¯ããžãã¯ããæããã§ãã æ··ä¹±ããŠããå ŽåïŒäžèŠãªæäœãšã¯ãåºæ¬ã¯ã©ã¹ã®ã³ã³ã¹ãã©ã¯ã¿ãŒã§ä»®æ³ããŒãã«ãžã®ãã€ã³ã¿ãŒãåæåããããšãæå³ããŸãã
èŠéãããæäœã¯1ã€ã ãã®ããã«æããŸã-ãã€ã³ãã¯ãããåãé€ãããšã§ããïŒ ããããããã°ã©ã ãåãæœè±¡ã¯ã©ã¹ããç¶æ¿ããäœåãã®ã¯ã©ã¹ãæã£ãŠããå Žåã1ã€ã®èªåçæã³ãã³ããåé€ãããšãããã©ãŒãã³ã¹ã«æ·±å»ãªåœ±é¿ãäžããå¯èœæ§ããããŸãã ãããŠãããã¯åœ±é¿ããŸãã ä¿¡ããããªãïŒ
Memset颿°
memsetïŒïŒé¢æ°ã®äž»ãªèãæ¹ã¯ãã¡ã¢ãªé åãäžå®ã®å€ïŒã»ãšãã©ã®å ŽåãŒãïŒã§åããããšã§ãã Cã§ã¯ãæ§é äœã®ãã¹ãŠã®ãã£ãŒã«ãããã°ããåæåããããã«äœ¿çšã§ããŸãã ãŸããä»®æ³ããŒãã«ãã€ã³ã¿ãŒããªãå ŽåãC ++ã¯ã©ã¹ãšã¡ã¢ãªãã±ãŒã·ã§ã³ã®Cæ§é äœã®éãã¯äœã§ããïŒ ååãšããŠãäœããããŒã¿-ãããã¯ããŒã¿ã§ãã æ¬åœã«åçŽãªã¯ã©ã¹ïŒC ++ 11ã®çšèª-
æšæºããã€ã¹ã®å ïŒãåæåããã«ã¯ãmemsetïŒïŒé¢æ°ã䜿çšããããšãã§ããŸãã ããããçè«çã«ã¯ãmemsetïŒïŒé¢æ°ã䜿çšããŠäžè¬ã«ãã¹ãŠã®ã¯ã©ã¹ãåæåã§ããŸãããçµæã¯ã©ããªããŸããïŒ èª€ã£ãmemsetïŒïŒãäžåºŠã«ãããšãä»®æ³ããŒãã«ãã€ã³ã¿ãŒã䜿çšã§ããªããªãããšããããŸãã ããããããã«åé¡ãçºçããŸããã¯ã©ã¹ã__declspecïŒnovtableïŒãšããŠå®£èšãããŠããå Žåã§ããããã¯å¯èœã§ããïŒ
åçïŒããã¯å¯èœã§ãããæ
éã«ããã§ããŸããã
ã¯ã©ã¹ã次ã®ããã«æžãæããŸããã¯ã©ã¹Aã®ã³ã³ãã³ãå
šäœã0xAAã«èšå®ããã¯ã€ãã¡ãœããã远å ããŸãã
class __declspec(novtable) A // { public: unsigned long long content_A; A(void) { cout << "++ A has been constructed" << endl; wipe(); };
ãã®å Žåã®ããã°ã©ã ã®åºåã¯éåžžã«æåŸ
ãããŸãã
++ A has been constructed ++ A has been wiped ++ B has been constructed Memory after placement new: E8 CA E8 3F 01 00 00 00 AA AA AA AA AA AA AA AA BB BB BB BB BB BB BB BB 11 11 11 11 11 11 11 11 -- B has been destructed -- A has been destructed
ãããŸã§ã®ãšããããã¹ãŠãããŸãæ©èœããŠããŸãã
ãã ããã³ã³ã¹ãã©ã¯ã¿ãŒã®è¡ãã³ã¡ã³ãåããŠãããã«ç¶ãè¡ã®ã³ã¡ã³ããå€ãããšã§ãwipeïŒïŒé¢æ°åŒã³åºãã®å Žæããããã«å€æŽããå¿
èŠããããŸãã ä»®æ³é¢æ°ïŒïŒé¢æ°ã®æåã®åŒã³åºãã§ã¯ãä»®æ³ããŒãã«ãã€ã³ã¿ãŒãç ŽæããŠãããããã©ã³ã¿ã€ã ãšã©ãŒãçºçããŸãã
++ A has been constructed ++ B has been constructed ++ A has been wiped Memory after placement new: AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA BB BB BB BB BB BB BB BB 11 11 11 11 11 11 11 11 -- B has been destructed -- A has been destructed
ãªããããèµ·ãã£ãã®ã§ããïŒ ã¯ã©ã¹Bã³ã³ã¹ãã©ã¯ã¿ãŒãä»®æ³ã¡ãœããããŒãã«ãžã®ãã€ã³ã¿ãŒãåæåããåŸã«ãwipeïŒïŒé¢æ°ãåŒã³åºãããŸããã ãã®çµæããã®ãã€ã³ã¿ãŒã¯å£åããŸããã ã€ãŸãã__ declspecïŒnovtableïŒã§å®£èšãããŠããå Žåã§ããä»®æ³ããŒãã«ãã€ã³ã¿ãŒã§ã¯ã©ã¹ãç¡å¹ã«ããªãã§ãã ããã å®å
šãªãŒãåã¯ãã€ã³ã¹ã¿ã³ã¹åãããªãã¯ã©ã¹ã®ã³ã³ã¹ãã©ã¯ã¿ãŒã§ã®ã¿é©åã§ããããã®å Žåã§ã现å¿ã®æ³šæãæã£ãŠè¡ãå¿
èŠããããŸãã
Memcpy颿°
memcpyïŒïŒã®å Žåãç»åã¯ãŸã£ããåãã§ãã ç¹°ãè¿ããŸãããçè«çã«ã¯ãã¡ã¢ãªå
ã®æšæºããã€ã¹ã§åãã³ããŒããããã«äœ¿çšã§ããŸãã ãã ããå®è·µã«ãã£ãŠå€æãããšãäžéšã®ããã°ã©ããŒã¯ãå¿
èŠãªå Žåãšããã§ãªãå Žåã«äœ¿çšããããšã奜ã¿ãŸãã ã¡ã¢ãªã«æšæºããã€ã¹ããªãã¿ã€ãã®å ŽåãmemcpyïŒïŒé¢æ°ã®äœ¿çšã¯ããã€ã¢ã¬ã©ã®æ»ãæž¡ã綱枡ãã®ãããªãã®ã§ãã1ã€ã®ééãã¯èŽåœçãªçµæã«ã€ãªããå¯èœæ§ããããããã¯ãšãŠã€ããªãç°¡åã§ãã äŸãšããŠïŒ
class __declspec(novtable) A { .... A(const A &source) { memcpy(this, &source, sizeof(*this)); } virtual void foo() { } .... }; class B : public A { .... };
ã³ããŒã³ã³ã¹ãã©ã¯ã¿ãŒã¯ãæœè±¡ã¯ã©ã¹ã®ä»®æ³ããŒãã«ãžã®ãã€ã³ã¿ãŒã«ãããžã¿ã«ãœãŠã«ãæããã®ãäœã§ãæžã蟌ãããšãã§ããŸããæ£ããå€ã¯ãšã«ããé
眮ãããŸãã ãã ãã代å
¥æŒç®åã®å®è£
ã§ã¯ãmemcpyïŒïŒé¢æ°ã䜿çšããããšã¯ã§ããªããªããŸããã
class __declspec(novtable) A { .... A &operator =(const A &source) { memcpy(this, &source, sizeof(*this)); return *this; } virtual void foo() { } .... }; class B : public A { .... };
ããã§ã代å
¥æŒç®åãšã³ããŒã³ã³ã¹ãã©ã¯ã¿ãŒãå®è³ªçã«åããã®ã§ãããšããäºå®ã«ã©ã®ããã«æ
£ããŠããããæãåºããŠãã ããã ãããããã¹ãŠãããã»ã©æªãããã§ã¯ãããŸããïŒå®éã«ã¯ã代å
¥æŒç®åã®ã³ãŒãã¯æ£ããåäœããããšããã§ããŸãããããã¯æ£ããããã§ããããããæã¯ãã®ããã«åœ¢æãããŠããããã§ãã ãã®ã³ãŒãã§ã¯ãå¥ã®ãªããžã§ã¯ãããä»®æ³ã¡ãœããã®ããŒãã«ãžã®ãã€ã³ã¿ãŒãã³ããŒãããŸãããã©ã®ãããªçµæã«ãªããã¯ããããŸããã
PVS-Studio
ãã®èšäºã¯ãç¥ç§çãª__declspecïŒnovtableïŒã«é¢ãã詳现ãªèª¿æ»ã®çµæãšããŠç»å ŽããŸããããŸããé«ã¬ãã«ã³ãŒãã§memsetïŒïŒããã³memcpyïŒïŒé¢æ°ã䜿çšããããšãå¯èœãã€äžå¯èœãªå ŽåããããŸãã éçºè
ã¯æã
ã
PVS-Studioã¢ãã©ã€ã¶ãŒãä»®æ³ããŒãã«ãã€ã³ã¿ãŒã«é¢ããèŠåãé »ç¹ã«çæããããšãå ±åããŠããŸãã ããã°ã©ãã¯ã__ declspecïŒnovtableïŒãååšããå Žåãä»®æ³ã¡ãœããããŒãã«ãŸãã¯ä»®æ³ããŒãã«ãã€ã³ã¿ãŒã¯ååšããªããšèããŠããŸãã ç§ãã¡ã¯ãã®åé¡ã«æ
éã«å¯ŸåŠãå§ãããããããã»ã©åçŽã§ã¯ãªãããšã«æ°ä»ããŸããã
ããã¯èŠããŠããå¿
èŠããããŸãã ã¯ã©ã¹ã®å®£èšæã«__declspecïŒnovtableïŒã䜿çšããå Žåãããã¯ã¯ã©ã¹ã«ä»®æ³ã¡ãœããããŒãã«ãžã®ãã€ã³ã¿ãŒãå«ãŸããŠããªãããšãæå³ããŸããïŒ ãããããã®ãã€ã³ã¿ãŒã¯åæåãããŠãããã©ããã§ã-ããã¯ãŸã£ããå¥ã®è³ªåã§ãã
__declspecïŒnovtableïŒã§å®£èšãããåºæ¬ã¯ã©ã¹ã®ã³ã³ã¹ãã©ã¯ã¿ãŒã§äœ¿çšãããå Žåã«ã®ã¿ãã¢ãã©ã€ã¶ãŒã«memsetïŒïŒ/ memcpyïŒïŒé¢æ°ãèªãããŸããã
ãããã«
æ®å¿µãªããããã®èšäºã¯ç¶æ¿ã«é¢é£ããå€ãã®è³æãã«ããŒã§ããŸããã§ããïŒããšãã°ãå€éç¶æ¿ã®ãããã¯ã¯å®å
šã«æããã«ãããŠããŸããã§ããïŒã ãã ãããã®æ
å ±ãããã¹ãŠãããã»ã©åçŽã§ã¯ãªããããšãçè§£ããé«ã¬ãã«ã®ãªããžã§ã¯ãã«é©çšãããäœã¬ãã«ã®é¢æ°ã䜿çšããåã«3åèãã䟡å€ãããããšãé¡ã£ãŠããŸãã ãããŠäžè¬çã«ãããã¯äŸ¡å€ããããŸããïŒ