【问题标题】:Can't remove code analysis warning C26462无法删除代码分析警告 C26462
【发布时间】:2021-12-09 16:32:57
【问题描述】:

示例代码:

void COptionsDlg::OnBnClickedButtonMoreSettings()
{
    CString strCaption = _T("");
    const auto pMoreSettingsButton = GetDlgItem(IDC_BUTTON_MORE_SETTINGS);

    if (pMoreSettingsButton == nullptr)
        return;

    pMoreSettingsButton->GetWindowText(strCaption);

    __pragma(warning(suppress:26414))
        auto pDlgOther = std::make_unique<COtherSettingsSheet>(strCaption);
    if (pDlgOther != nullptr)
    {
        pDlgOther->DoModal();
    }
}

为什么编译器仍然抱怨这一行:

它仍然说:

C26462pMoreSettingsButton指向的值只赋值一次,标记为指向const的指针(con.4)。

我正在使用 Visual Studio 2022 Preview 6,并且在其他类文件中也注意到了这一点。是我做错了什么还是我应该向 Microsoft 解决的错误?

【问题讨论】:

  • 我认为它希望你做const CWnd* pMoreSettingsButton = ...;const auto 使它成为CWnd* const - 指针本身是常量,而不是指针。在我看来,这条建议的价值值得怀疑。
  • @IgorTandetnik 你是对的 - 像这样改变它会阻止它显示。
  • 不相关,但unique_ptr 再往下不是真的必要。您可以将对话框设置为局部变量,即COtherSettingsSheet dlg(strCaption); dlg.DoModal();,然后在函数退出时清除所有内容。
  • @IInspectable 我这样做的原因有时是代码分析表明函数堆栈大小太大或其他什么(不太记得)。但是像这样进行更改,这些警告就会消失。
  • 这是有道理的。堆栈大小非常有限(默认为 1MB),因此将大对象放在堆栈上会很快耗尽。

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


【解决方案1】:

以下程序抓住了问题的要点,但不失一般性:

int* foo() { return nullptr; }

int main() {
    const auto p = foo();  // C26462
}

它会产生一个C26462 诊断,然后继续提供解决方案:

将其标记为指向const的指针

您可能认为const auto 正是这样做的,但事实并非如此。

编译器需要推断用auto 替换什么。它查看foo() 的函数声明,并明确得出结论,auto 应该替换为int*。那部分不是很有趣。这里唯一的惊喜可能是,C++ 走的是最少惊喜的路线。

那么,如果autoint* 替换,很明显const auto 应该变成const int*,即指向const 的指针,正如诊断消息所建议的那样。那为什么代码分析器还在报错呢?

嗯,在设计编程语言时,选择最少惊喜的路线并不是唯一的选择,C++ 也不会羞于积极探索那种设计空间也! const 关键字的放置当然属于该类别:

广义而言,const 适用于紧靠其左侧的任何内容。这很简单,看似如此,与 C++ 非常不同。当然,还有一个特殊的规则可以看到如此频繁的应用,以至于我们几乎完全忘记了它的特殊性:如果const 的左边没有任何东西,那么它就会应用到它右边的任何东西上。对于值,这无关紧要:const intint const 意思相同。但是,当涉及指针时,事情会变得更加有趣。 const int*int* const 意味着完全不同的东西。前者指定一个“指向const的指针”,而后者是一个const指针”

回到这里的直接问题,const auto 被转换为 auto const(通过特殊的 const 规则),最后 auto 被替换,产生 int* const(或 CWnd* const 为在最初的问题陈述中)。这不是一个“指向const”的指针。要解决此问题,您有两种选择:

  • 命名具体类型,即CWnd const*,或
  • auto 解决其他问题,例如auto const*(注意尾部的 * 导致编译器推断类型 CWnd,并允许您对指针进行 cv 限定)

无论哪种方式,您都应该考虑使用"consistent const", also referred to as "east const",而忘记const 甚至还有一个特殊规则。

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-11-03
  • 2018-07-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多