And*_*kle 1 mfc code-analysis visual-c++ visual-studio-2022
示例代码:
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();
}
}
Run Code Online (Sandbox Code Playgroud)
为什么编译器仍然抱怨这一行:
它仍然说:
C26462: by 指向的值
pMoreSettingsButton
仅分配一次,将其标记为指向const
(con.4)的指针。
我正在使用 Visual Studio 2022 Preview 6,并且我在其他类文件中注意到了这一点。这是我做错了什么还是我应该向 Microsoft 解决的错误?
以下程序抓住了问题的要点,但不失一般性:
int* foo() { return nullptr; }
int main() {
const auto p = foo(); // C26462
}
Run Code Online (Sandbox Code Playgroud)
它产生C26462诊断,并继续提供解决方案:
将其标记为指向的指针
const
您可能认为这const auto
正是这样做的,但事实并非如此。
编译器需要推断要替换什么auto
。它查看 的函数声明foo()
并明确得出结论,auto
应该替换int*
。那部分不是很有趣。这里唯一令人惊讶的可能是,C++ 正在遵循最少意外的路线。
因此,如果auto
被替换为int*
,显然应该const auto
变成const int*
,即指向 的指针const
,正如诊断消息所建议的那样。那么为什么代码分析器仍然抱怨呢?
好吧,在设计编程语言时,采取最少意外的路线并不是唯一的选择,而且 C++ 也不羞于积极探索该设计空间!关键字的放置const
肯定属于该类别:
从广义上讲,const
适用于紧邻其左侧的任何内容。这很简单,看似简单,与 C++ 非常不同。当然,还有一个特殊的规则,它的应用如此频繁,以至于我们几乎完全忘记了它的特殊性:如果左侧没有任何内容,const
那么它将应用于紧邻其右侧的任何内容。对于价值观来说,这并不重要:const int
并且int const
意味着同样的事情。然而,当涉及到指针时,事情就变得更有趣了。const int*
并int* const
意味着完全不同的东西。前者指定“指向const
”的指针,而后者指定“const
指针”。
回到这里直接的问题,const auto
被翻译成auto const
(通过特殊const
规则),最后auto
被替换,产生int* const
(或CWnd* const
如最初的问题陈述中那样)。这不是一个“指向const
”的指针。要解决该问题,您有两种选择:
CWnd const*
,或auto
解析为其他内容,例如(请注意导致编译器推断类型的auto const*
尾随,并允许您对指针对象进行 cv 限定)*
CWnd
无论哪种方式,您都应该考虑使用“一致const
”,也称为“东部const
”,并且忘记甚至有一个特殊的规则const
。