【问题标题】:Pointer decay warning (C26485) and passing NOTIFYICONDATA member variable to _tcscpy_s指针衰减警告 (C26485) 并将 NOTIFYICONDATA 成员变量传递给 _tcscpy_s
【发布时间】:2021-10-26 17:47:24
【问题描述】:

示例代码:

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

无论如何,我知道我可以使用&amp;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);

【问题讨论】:

    标签: visual-c++ code-analysis


    【解决方案1】:

    &amp; 的正确位置是:

    _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 函数旨在通过检查缓冲区大小来实现secure;撒谎,你就违背了这个安全的目的。

    只是省略第二个参数,让它被推导,这也应该修复警告(真正修复,而不是抑制):

    _tcscpy_s(m_sNTD.szInfoTitle, (LPCTSTR)strInfoTitle); 
    _tcscpy_s(m_sNTD.szInfo, (LPCTSTR)strInfo); 
    _tcscpy_s(m_sNTD.szTip, (LPCTSTR)strTip); 
    

    【讨论】:

    • 感谢您的解释和更正!这些年都错了!
    猜你喜欢
    • 2021-07-17
    • 1970-01-01
    • 2012-09-22
    • 2021-12-04
    • 2012-08-01
    • 1970-01-01
    • 2017-05-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多