错误 C4146:一元减号运算符应用于无符号类型,结果仍然无符号

error C4146: unary minus operator applied to unsigned type, result still unsigned

本文关键字:无符号 应用于 运算符 类型 结果 C4146 一元 错误      更新时间:2023-10-16

我尝试在Visual Studio 2013中构建CRF++,并在最后一行收到此错误:

array_[begin + siblings[i].code].base =
            value_ ?
            static_cast<array_type_>(-value_[siblings[i].left]-1) :
            static_cast<array_type_>(-siblings[i].left-1);

错误 C4146:一元减号运算符应用于无符号类型,结果 仍未签名

具体来说,它在darts.h中,第189行。

我在Visual Studio 2015中再次构建,然后没有错误。

如何在Visual Studio 2013中解决此问题?

C4146 不应该是一个错误。这只是一个警告。如果您将其视为错误,则意味着有人以这种方式配置了它,很可能是无意的。这是没有道理的。

查找并撤消将其变成错误的更改。然后,您可以根据需要禁用它。

对于其他人,我想添加另一个答案,以防他们像我一样偶然遇到那个错误。

即使我的编译器中的"威胁警告为错误"已关闭,我也必须在显示错误的标头文件中使用#pragma warning(disable:4146)编译我的项目。对你来说,它会在飞镖里面。

请注意,在我的项目中全局禁用警告不起作用(编译器/wd4146(,直接在头文件中需要编译指示行。

siblings变量也应用了一元减号,也许这是罪魁祸首?此外,如果它是模板化代码,则无法真正确定value_会短,int或长,除非通过static_assert左右断言。我们只能猜测,因为您没有提供有关实际使用的类型或可重现的内容的信息。另外,您是否在VS2015中使用了完全相同的项目进行编译?如果没有,警告可能只是在那里被禁用。

无论如何,假设它是VS2013中的一个错误,它可能不会再得到修复,因此您可以尝试找到解决方法。首先将该语句分解为较小的语句,直到您确切地知道哪个部分是问题所在(或者,到那时问题已经消失了,因为它与编译器错误有关(。然后用 #pragma warning ( disable : 4146 ) 禁止警告,包装在条件指令中,使其仅对 VS2013 有效#if _MSC_VER > 1800 && _MSC_VER < 1900应该可以正常工作。在语句后再次启用警告。添加有关禁用警告原因的注释,并将更改作为补丁提交到CRF ++。

试试这个:

int tmp = static_cast<int>(siblings[i].left);
array_[begin + siblings[i].code].base =
            value_ ?
            static_cast<array_type_>(-value_[siblings[i].left]-1) :
            static_cast<array_type_>(-tmp - 1);

对于任何遇到真正令人困惑的部分的人:

这不应该是一个错误。 事实上,有一堆警告说Visual Studio默认错误地变成错误。 编译器可以为他们想要的任何内容添加警告,但为有效代码抛出错误只是一个错误。

罪魁祸首是"SDL 检查"选项。 它以添加运行时堆栈检查之类的东西而闻名,这很好,但它们偷偷地加入了一些肮脏的东西:"并启用额外的安全相关警告作为错误"。 这需要关闭才能稍微接近标准C++编译器。