【问题标题】:LPNMITEMACTIVATE and code analysis (C26462)LPNMITEMACTIVATE 和代码分析 (C26462)
【发布时间】:2021-10-25 08:45:42
【问题描述】:

为什么在 LPNMITEMACTIVATE 的 SDK 的源代码中,它是用 left 的星号定义的?

typedef struct tagNMITEMACTIVATE
{
    NMHDR   hdr;
    int     iItem;
    int     iSubItem;
    UINT    uNewState;
    UINT    uOldState;
    UINT    uChanged;
    POINT   ptAction;
    LPARAM  lParam;
    UINT    uKeyFlags;
} NMITEMACTIVATE, *LPNMITEMACTIVATE;

我总是习惯指针在右边。无论哪种方式,代码如下:

const LPNMITEMACTIVATE pNMItem = reinterpret_cast<LPNMITEMACTIVATE>(pNMHDR);

仍会标记 const (C26462) 警告:

如果我将代码更改为:

const NMITEMACTIVATE* pNMItem = reinterpret_cast<LPNMITEMACTIVATE>(pNMHDR);

警告将消失。

【问题讨论】:

标签: visual-c++ mfc code-analysis


【解决方案1】:

我在 Visual Studio 2022 上试过这个,首先警告 C26462 没有默认启用。也许您使用的是早期版本,或者我的安装有些奇怪。

手动启用警告后,我可以通过多次分配pNMItem 来消除警告:

LPNMITEMACTIVATE pNMItem = nullptr;
pNMItem = reinterpret_cast<LPNMITEMACTIVATE>(pNMHDR);

这有什么用?

或者可以按照其他答案中的建议进行修复。但是你可能会有额外的问题,因为pNMHDR 可能被声明为LPNMHDR,所以你必须重写更多的行:

NMHDR hdr = { 0 };
const NMHDR* pNMHDR = reinterpret_cast<NMHDR*>(&hdr);
const NMITEMACTIVATE* pNMItem = reinterpret_cast<const NMITEMACTIVATE*>(pNMHDR);

这可能会浪费很多时间。请注意,如果您正在编写应该在任何系统上运行的代码,建议您使用额外的合规性。但是 MFC 与 Windows 绑定,所以这不是一个真正的问题。 MFC 和 Windows 仍在使用 16 位 Windows 遗留的“长指针”废话,它们本身不兼容,因此请考虑关闭其中一些警告。

【讨论】:

  • 我明白了。我包括将这些警告保留原样。我将其设置为禁止所有 SDK 警告(使用 External Includes 设置)。这只是我的代码....所以我不会太担心这个。但我将继续通过我的文件来修改铸件并改进我使用内存的方式。
  • 这是一个让您自己的代码尽可能兼容的好计划,而不必担心 Windows/MFC 标头的代码分析警告。我个人会将其保留为默认设置。我认为默认情况下应该关闭特定的警告 C26462。这是预发布的VS2022,可能他们还在思考设置。
【解决方案2】:

这是标准的 C/C++

就像这个(不可运行的)代码sn-p:

typedef int *LPINT;
//  typedef int* LPINT;  // you could write this, it's exactly the
                         // the same as above

int main()
{
  LPINT pint;
  int* pint2;

  *pint = *pint2;
}

pintpint2 都是指向int 的指针。顺便说一句,这是在 typedef 后面隐藏指针类型,这是一个坏主意(但在旧的 MS 时代被认为是个好主意),但出于兼容性原因,许多 Microsoft 标头仍然具有这些 typedef sometype *LPsometype; typedef。

另一个更接近您所指的 MS 标头的示例:

这个:

typedef struct tagNMITEMACTIVATE
{
  int   hdr;
  int     iItem;
} NMITEMACTIVATE, *LPNMITEMACTIVATE;

等价于:

typedef struct tagNMITEMACTIVATE
{
  int   hdr;
  int     iItem;
} NMITEMACTIVATE;

typedef struct tagNMITEMACTIVATE *LPNMITEMACTIVATE;

【讨论】:

  • 我理解那部分。但是LPNMITEMACTIVATE的定义是*NMITEMACTIVATE。我会永远那样声明一个指针。无论哪种方式,代码分析都说我没有将指针设置为const。只有当我停止使用 LPNMITEMACTIVATE 时,警告才会停止。
  • @AndrewTruckle 好的,我在回答 “为什么在 LPNMITEMACTIVATE 的 SDK 的源代码中它是用左侧的星号定义的?” 的一部分这个问题。也许你应该稍微修改一下这个问题。我应该删除这个答案吗?
  • 从技术上讲,您的回答并没有向我解释为什么 asterix 在左侧。当我将结构放在我的问题中时,我知道它就在那里。我要澄清的是为什么代码分析警告不会消失。我想知道这是否是因为指针的 LP 版本的 * 在左边而不是右边。这是一种预感。
  • @AndrewTruckle 已修改。这是否回答了“左边的星号”问题?
  • 对于参数说,你是否会像这样声明一个指向int 的指针:*int my_int_pointer;?这完全有效吗?
【解决方案3】:

对于指针 const 可以应用于指针指向的类型:

const NMITEMACTIVATE* p;

NMITEMACTIVATE const* p;

或者它可以应用于指针变量本身:

NMITEMACTIVATE* const p;

现在如果你有 typedef:

typedef NMITEMACTIVATE *PNMITEMACTIVATE;

const 不适用于被指向的类型。无论哪种方式,指针本身都是恒定的:

const PNMITEMACTIVATE p;
PNMITEMACTIVATE const p;

为避免这种混淆,最好不要使用原始指针类型定义(也不要定义它们)。

【讨论】:

    猜你喜欢
    • 2021-12-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-31
    • 2010-12-05
    • 2021-12-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多