【发布时间】:2018-05-15 12:53:45
【问题描述】:
我有一个使用ATL 数据库访问的简单类。
所有函数都定义在一个头文件中。
有问题的函数都是一样的。有一些宏正在使用中。生成的代码是这样的
void InitBindings()
{
if (sName) // Static global char*
m_sTableName = sName; // Save into member
{ AddCol("Name", some_constant_data... _GetOleDBType(...), ...); };
{ AddCol("Name1", some_other_constant_data_GetOleDBType(...), ...); };
...
}
AddCol 返回对结构的引用,但如您所见,它被忽略了。
当我查看汇编代码时,我有一个使用 6 个 AddCol 调用的函数,我可以看到该函数需要 2176 字节的堆栈空间。我有需要 20kb 或更多的功能。在调试器中,我可以看到堆栈根本没有使用。 (全部初始化为 0xCC 从未接触过)
见最后的汇编代码。
问题可以在 VS-2015 和 VS-2017 中看到。
仅在调试模式下。
在发布模式下,该函数根本不保留额外的堆栈空间。
我看到的唯一规则是;更多的 AddCol 调用,将导致更多的堆栈被保留。我可以看到每个 AddCol 调用保留了大约 500 字节。
再次:该函数不返回任何对象,它返回对绑定信息的引用。
我已经在函数前面使用了以下编译指示(但在标题中的类定义内):
__pragma(runtime_checks("", off)) __pragma(optimize("ts", on)) __pragma(strict_gs_check(push, off))
但无济于事。这个编译指示应该打开优化,关闭运行时检查和堆栈检查。如何减少分配的这个不需要的堆栈空间。在某些情况下,当使用此函数时,我可以在调试版本中看到堆栈溢出。发布版本没有问题。
; 325 : BIND_BEGIN(CMasterData, _T("tblMasterData"))
push ebp
mov ebp, esp
sub esp, 2176 ; 00000880H
push ebx
push esi
push edi
mov DWORD PTR _this$[ebp], ecx
mov eax, OFFSET ??_C@_1BM@GOLNKAI@?$AAt?$AAb?$AAl?$AAM?$AAa?$AAs?$AAt?$AAe?$AAr?$AAD?$AAa?$AAt?$AAa?$AA?$AA@
test eax, eax
je SHORT $LN2@InitBindin
push OFFSET ??_C@_1BM@GOLNKAI@?$AAt?$AAb?$AAl?$AAM?$AAa?$AAs?$AAt?$AAe?$AAr?$AAD?$AAa?$AAt?$AAa?$AA?$AA@
mov ecx, DWORD PTR _this$[ebp]
add ecx, 136 ; 00000088H
call DWORD PTR __imp_??4?$CStringT@_WV?$StrTraitMFC_DLL@_WV?$ChTraitsCRT@_W@ATL@@@@@ATL@@QAEAAV01@PB_W@Z
$LN2@InitBindin:
; 326 : // Columns:
; 327 : B$C_IDENT (_T("Id"), m_lId);
push 0
push 0
push 1
push 4
push 0
call ?_GetOleDBType@ATL@@YAGAAJ@Z ; ATL::_GetOleDBType
add esp, 4
movzx eax, ax
push eax
push 0
push OFFSET ??_C@_15NCCOGFKM@?$AAI?$AAd?$AA?$AA@
mov ecx, DWORD PTR _this$[ebp]
call ?AddCol@CDBAccess@DB@@QAEAAUS_BIND@2@PB_WKGKW4TYPE@32@0_N@Z ; DB::CDBAccess::AddCol
; 328 : B$C (_T("Name"), m_szName);
push 0
push 0
push 0
push 122 ; 0000007aH
mov eax, 4
push eax
call ?_GetOleDBType@ATL@@YAGQA_W@Z ; ATL::_GetOleDBType
add esp, 4
movzx ecx, ax
push ecx
push 4
push OFFSET ??_C@_19DINFBLAK@?$AAN?$AAa?$AAm?$AAe?$AA?$AA@
mov ecx, DWORD PTR _this$[ebp]
call ?AddCol@CDBAccess@DB@@QAEAAUS_BIND@2@PB_WKGKW4TYPE@32@0_N@Z ; DB::CDBAccess::AddCol
; 329 : B$C (_T("Data"), m_data);
push 0
push 0
push 0
push 4
push 128 ; 00000080H
call ?_GetOleDBType@ATL@@YAGAAVCComBSTR@1@@Z ; ATL::_GetOleDBType
add esp, 4
movzx eax, ax
push eax
push 128 ; 00000080H
push OFFSET ??_C@_19IEEMEPMH@?$AAD?$AAa?$AAt?$AAa?$AA?$AA@
mov ecx, DWORD PTR _this$[ebp]
call ?AddCol@CDBAccess@DB@@QAEAAUS_BIND@2@PB_WKGKW4TYPE@32@0_N@Z ; DB::CDBAccess::AddCol
【问题讨论】:
标签: c++ mfc stack visual-studio-2017 atl