gpt4 book ai didi

c++ - 警告 C6273 : Non-integer passed as _Param_(2) when an integer is required

转载 作者:行者123 更新时间:2023-11-28 01:55:40 25 4
gpt4 key购买 nike

我有这个方法:

void CMeetingScheduleAssistantDlg::RestartProgram()
{
RESTART_THIS_MFC_APP;
}

它调用定义的宏:

#define RESTART_THIS_MFC_APP \
{ \
HWND _hWndMain = AfxGetApp()->m_pMainWnd->GetSafeHwnd(); \
DWORD _dwProcessID = (DWORD)_getpid(); \
TCHAR _cFilespec[_MAX_PATH + 1]; \
if (::GetModuleFileName(AfxGetInstanceHandle(), _cFilespec,_MAX_PATH) == 0) \
AfxMessageBox(_T("ERROR: Could not obtain full filespec of this application to restart it."), MB_OK|MB_ICONSTOP); \
else \
{ \
CString strAppFilespec(_cFilespec); \
; \
LPTSTR lpszFilename = ::PathFindFileName(_cFilespec); \
_tcscpy_s(lpszFilename,_MAX_PATH - (lpszFilename - _cFilespec),_T("AppRestarter.exe") ); \
; \
CString strAppRestarterFilespec(_cFilespec); \
; \
CString strCmdLine ; \
strCmdLine.Format(_T("%ld %ld \"%s\""),_hWndMain,_dwProcessID,(LPCTSTR)strAppFilespec); \
; \
HINSTANCE hProcess = ::ShellExecute(NULL,_T("open"),(LPCTSTR)strAppRestarterFilespec, \
(LPCTSTR)strCmdLine,_T(".\\"), SW_HIDE); \
if ( (DWORD)(DWORD_PTR)hProcess <= 32) \
AfxMessageBox(_T("ERROR: Could not run application restarter."), MB_OK|MB_ICONSTOP); \
} \
}

以上是提供给我的第三方宏,它与应用程序重启器可执行文件一起工作。原作者已不在。

应用程序构建并正常运行。但是我收到代码分析错误:

warning C6273: Non-integer passed as Param(2) when an integer is required in call to 'ATL::CStringT >

::Format' Actual type: 'struct HWND__ *': if a pointer value is being passed, %p should be used.

_hWndMain 确实是 HWND 类型,但我不能使用 %p 作为格式代码。如果我这样做,应用程序重新启动器将失败并告诉我它希望此参数为数字。

如您所见,我恢复使用 %ld,我认为这是正确的。

是否可以通过更改我的代码来抑制此警告?或者这只是我必须忍受的误报?

最佳答案

不是误报;警告是正确的,并发现了一个错误。 %ld是不对的,因为指针不是整数。语言规范在这个事实上很清楚,所以 %ld是错误的,因为它指示函数将指针值解释为长整数。这可能出错的多种方式之一是针对 64 位处理器,其中指针为 64 位宽但整数(包括 long s,只有 32 位宽)。 %ld将砍掉高位。

CString<T>::Format , 您必须按照与 printf 相同的规则进行游戏,这就是警告告诉您需要使用 %p 的原因传递指针值。 HWND的原因被认为是指针是因为这是在 Windows header 中定义类型的方式。从技术上讲,它不是指针,只是一个不透明的值,但指针语义通常是合适的,可以避免错误。

你说使用 %p不是一个选项,因为您收到参数不是数字的错误。我猜那是因为 %p导致值以某种格式打印 CString<T>::Format认为适合指针值,可能是十六进制的,甚至可能是 0x前缀,但是您将该格式化字符串传递给的函数并不期望这样。

因此,您需要明确解释 HWND在与 %ld 一起使用之前将值作为数值.这不仅会消除警告,还会为您提供正确的语义。但是您需要仔细选择您将使用哪种类型来表示它。你的第一直觉可能是 size_t , 但标准不保证与指针具有相同的宽度。它将在 Windows 32 位和 64 位上“工作”,但在技术上无效。相反,为了安全起见,更喜欢 intptr_tuintptr_t ,具体取决于您想要地址的有符号表示还是无符号表示。对于格式字符串,使用 %Id , %Ix , 或 %IX .从您当前代码的外观来看,您可能需要 %Id .您可能还需要明确指出字段的大小,具体取决于消费者期望的格式。

strCmdLine.Format(_T("%Id %ld \"%s\""),
reinterpret_cast<intptr_t>(_hWndMain),
_dwProcessID,
static_cast<LPCTSTR>(strAppFilespec));

您需要确保包含了 <inttypes.h> .

(请注意,%I 格式说明符是 Microsoft 的发明,因此不可移植。在其他编译器上,您会使用 use the standard macros from inttypes.h 。我认为 Microsoft 的实现中不存在这些,尽管我没有编译器在我面前。也许你能证明我错了?)

关于c++ - 警告 C6273 : Non-integer passed as _Param_(2) when an integer is required,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41313666/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com