指针衰减警告 (C26485) 并将 NOTIFYICONDATA 成员变量传递给 _tcscpy_s
Pointer decay warning (C26485) and passing NOTIFYICONDATA member variable to _tcscpy_s
示例代码:
void CMeetingScheduleAssistantDlg::CreateBackupTrayNotification(CString strInfoTitle, CString strInfo, CString strTip)
{
::ZeroMemory(&m_sNTD, sizeof(NOTIFYICONDATA));
m_sNTD.cbSize = sizeof(NOTIFYICONDATA);
m_sNTD.hWnd = GetSafeHwnd();
m_sNTD.uID = 0;
m_sNTD.uFlags = NIF_MESSAGE | NIF_ICON | NIF_TIP | NIF_INFO;
m_sNTD.dwInfoFlags = NIIF_INFO;
m_sNTD.uCallbackMessage = WM_MSA_BACKUP_NOTIFICATION;
m_sNTD.uTimeout = 20000; // 20 Seconds
m_sNTD.hIcon = LoadIcon(AfxGetResourceHandle(),
MAKEINTRESOURCE(IDR_MAINFRAME));
_tcscpy_s(m_sNTD.szInfoTitle, gsl::narrow<rsize_t>(strInfoTitle.GetLength()) + 1, (LPCTSTR)strInfoTitle);
_tcscpy_s(m_sNTD.szInfo, gsl::narrow<rsize_t>(strInfo.GetLength()) + 1, (LPCTSTR)strInfo);
_tcscpy_s(m_sNTD.szTip, gsl::narrow<rsize_t>(strTip.GetLength()) + 1, (LPCTSTR)strTip);
Shell_NotifyIcon(NIM_ADD, &m_sNTD);
}
忽略 (LPCTSTR)
转换,因为我添加了全局 pragma
来忽略警告。我的问题与这些行有关:
_tcscpy_s(m_sNTD.szInfoTitle, gsl::narrow<rsize_t>(strInfoTitle.GetLength()) + 1, (LPCTSTR)strInfoTitle);
_tcscpy_s(m_sNTD.szInfo, gsl::narrow<rsize_t>(strInfo.GetLength()) + 1, (LPCTSTR)strInfo);
_tcscpy_s(m_sNTD.szTip, gsl::narrow<rsize_t>(strTip.GetLength()) + 1, (LPCTSTR)strTip);
m_sNTD
是一个NOTIFYICONDATA
结构:
typedef struct _NOTIFYICONDATAA {
DWORD cbSize;
HWND hWnd;
UINT uID;
UINT uFlags;
UINT uCallbackMessage;
HICON hIcon;
#if ...
CHAR szTip[64];
#else
CHAR szTip[128];
#endif
DWORD dwState;
DWORD dwStateMask;
CHAR szInfo[256];
union {
UINT uTimeout;
UINT uVersion;
} DUMMYUNIONNAME;
CHAR szInfoTitle[64];
DWORD dwInfoFlags;
GUID guidItem;
HICON hBalloonIcon;
} NOTIFYICONDATAA, *PNOTIFYICONDATAA;
我收到可怕的指针衰减警告 (C26485)。可以看到,有问题的成员变量是:
CHAR szInfoTitle[64];
CHAR szInfo[256];
CHAR szTip[128];
旁注:不确定 if ...
是关于什么的。另外,我的结构实际上指向一个 NOTIFYICONDATAW
所以成员变量是 WCHAR
.
无论如何,我知道我可以通过使用 &varname[0]
来抑制指针衰减警告。但在这种情况下它不起作用:
_tcscpy_s(m_sNTD.&szInfoTitle[0], gsl::narrow<rsize_t>(strInfoTitle.GetLength()) + 1, (LPCTSTR)strInfoTitle);
_tcscpy_s(m_sNTD.&szInfo[0], gsl::narrow<rsize_t>(strInfo.GetLength()) + 1, (LPCTSTR)strInfo);
_tcscpy_s(m_sNTD.&szTip[0], gsl::narrow<rsize_t>(strTip.GetLength()) + 1, (LPCTSTR)strTip);
&
的正确位置是:
_tcscpy_s(&m_sNTD.szInfoTitle[0], gsl::narrow<rsize_t>(strInfoTitle.GetLength()) + 1, (LPCTSTR)strInfoTitle);
_tcscpy_s(&m_sNTD.szInfo[0], gsl::narrow<rsize_t>(strInfo.GetLength()) + 1, (LPCTSTR)strInfo);
_tcscpy_s(&m_sNTD.szTip[0], gsl::narrow<rsize_t>(strTip.GetLength()) + 1, (LPCTSTR)strTip);
但实际上你用错了_tcscpy_s
。第二个参数是目标缓冲区大小,而不是源缓冲区。 _s
函数旨在通过检查缓冲区大小 s 安全;撒谎,你就破坏了这种安全的目的。
只需要省略第二个参数,让它推导即可,这样应该也修复了警告(真的修复,不是打压):
_tcscpy_s(m_sNTD.szInfoTitle, (LPCTSTR)strInfoTitle);
_tcscpy_s(m_sNTD.szInfo, (LPCTSTR)strInfo);
_tcscpy_s(m_sNTD.szTip, (LPCTSTR)strTip);
示例代码:
void CMeetingScheduleAssistantDlg::CreateBackupTrayNotification(CString strInfoTitle, CString strInfo, CString strTip)
{
::ZeroMemory(&m_sNTD, sizeof(NOTIFYICONDATA));
m_sNTD.cbSize = sizeof(NOTIFYICONDATA);
m_sNTD.hWnd = GetSafeHwnd();
m_sNTD.uID = 0;
m_sNTD.uFlags = NIF_MESSAGE | NIF_ICON | NIF_TIP | NIF_INFO;
m_sNTD.dwInfoFlags = NIIF_INFO;
m_sNTD.uCallbackMessage = WM_MSA_BACKUP_NOTIFICATION;
m_sNTD.uTimeout = 20000; // 20 Seconds
m_sNTD.hIcon = LoadIcon(AfxGetResourceHandle(),
MAKEINTRESOURCE(IDR_MAINFRAME));
_tcscpy_s(m_sNTD.szInfoTitle, gsl::narrow<rsize_t>(strInfoTitle.GetLength()) + 1, (LPCTSTR)strInfoTitle);
_tcscpy_s(m_sNTD.szInfo, gsl::narrow<rsize_t>(strInfo.GetLength()) + 1, (LPCTSTR)strInfo);
_tcscpy_s(m_sNTD.szTip, gsl::narrow<rsize_t>(strTip.GetLength()) + 1, (LPCTSTR)strTip);
Shell_NotifyIcon(NIM_ADD, &m_sNTD);
}
忽略 (LPCTSTR)
转换,因为我添加了全局 pragma
来忽略警告。我的问题与这些行有关:
_tcscpy_s(m_sNTD.szInfoTitle, gsl::narrow<rsize_t>(strInfoTitle.GetLength()) + 1, (LPCTSTR)strInfoTitle);
_tcscpy_s(m_sNTD.szInfo, gsl::narrow<rsize_t>(strInfo.GetLength()) + 1, (LPCTSTR)strInfo);
_tcscpy_s(m_sNTD.szTip, gsl::narrow<rsize_t>(strTip.GetLength()) + 1, (LPCTSTR)strTip);
m_sNTD
是一个NOTIFYICONDATA
结构:
typedef struct _NOTIFYICONDATAA {
DWORD cbSize;
HWND hWnd;
UINT uID;
UINT uFlags;
UINT uCallbackMessage;
HICON hIcon;
#if ...
CHAR szTip[64];
#else
CHAR szTip[128];
#endif
DWORD dwState;
DWORD dwStateMask;
CHAR szInfo[256];
union {
UINT uTimeout;
UINT uVersion;
} DUMMYUNIONNAME;
CHAR szInfoTitle[64];
DWORD dwInfoFlags;
GUID guidItem;
HICON hBalloonIcon;
} NOTIFYICONDATAA, *PNOTIFYICONDATAA;
我收到可怕的指针衰减警告 (C26485)。可以看到,有问题的成员变量是:
CHAR szInfoTitle[64];
CHAR szInfo[256];
CHAR szTip[128];
旁注:不确定 if ...
是关于什么的。另外,我的结构实际上指向一个 NOTIFYICONDATAW
所以成员变量是 WCHAR
.
无论如何,我知道我可以通过使用 &varname[0]
来抑制指针衰减警告。但在这种情况下它不起作用:
_tcscpy_s(m_sNTD.&szInfoTitle[0], gsl::narrow<rsize_t>(strInfoTitle.GetLength()) + 1, (LPCTSTR)strInfoTitle);
_tcscpy_s(m_sNTD.&szInfo[0], gsl::narrow<rsize_t>(strInfo.GetLength()) + 1, (LPCTSTR)strInfo);
_tcscpy_s(m_sNTD.&szTip[0], gsl::narrow<rsize_t>(strTip.GetLength()) + 1, (LPCTSTR)strTip);
&
的正确位置是:
_tcscpy_s(&m_sNTD.szInfoTitle[0], gsl::narrow<rsize_t>(strInfoTitle.GetLength()) + 1, (LPCTSTR)strInfoTitle);
_tcscpy_s(&m_sNTD.szInfo[0], gsl::narrow<rsize_t>(strInfo.GetLength()) + 1, (LPCTSTR)strInfo);
_tcscpy_s(&m_sNTD.szTip[0], gsl::narrow<rsize_t>(strTip.GetLength()) + 1, (LPCTSTR)strTip);
但实际上你用错了_tcscpy_s
。第二个参数是目标缓冲区大小,而不是源缓冲区。 _s
函数旨在通过检查缓冲区大小 s 安全;撒谎,你就破坏了这种安全的目的。
只需要省略第二个参数,让它推导即可,这样应该也修复了警告(真的修复,不是打压):
_tcscpy_s(m_sNTD.szInfoTitle, (LPCTSTR)strInfoTitle);
_tcscpy_s(m_sNTD.szInfo, (LPCTSTR)strInfo);
_tcscpy_s(m_sNTD.szTip, (LPCTSTR)strTip);