【问题标题】:in visual studio 2015 community c++, how do I fix warning C4838: conversion from 'unsigned int' to 'int' requires a narrowing conversion在 Visual Studio 2015 社区 C++ 中,如何修复警告 C4838:从 'unsigned int' 到 'int' 的转换需要缩小转换
【发布时间】:2015-11-27 19:24:59
【问题描述】:

我正在尝试在 win32 API(无 mfc)上编写一些直接的 c++。 使用这个更现代的 c++ 编译器,我得到:

警告 C4838:从“unsigned int”到“int”的转换需要缩小转换

它发生在这段代码中:

EvMap<DlgCtl> DlgCtl::_evMap [] = {
    {IDC_LIST, NM_CLICK, & DlgCtl::Pik},
    {0}
};

riiiiight 在右大括号前面。控件 id 的 0 表示数组的结尾。 此代码将控件 ID 和事件 ID 映射到类似于 MFC 的本地函数。

我想缩小转换意味着您在将 unsigned in 隐式转换为 int 时会丢失精度(因为 unsigned 可以容纳 > 32767 而 int 不能)。
我不确定 unsigned int 是什么。有一个 0,但那是一个有符号整数,对吧? 下面的代码使用列表在 winproc-ish 类中调度类本地函数。

template <class T>
struct EvMap {int ctrl, evnt;  void (T::* func)(LPARAM l);};


template <class T>
bool DoEvMap (T *ths, EvMap<T> *evMap, int ctrl, int evnt, LPARAM l)
{
//DBG("DoEvMap ctrl=`d evnt=`d", ctrl, evnt);
    for (int i = 0;  evMap [i].ctrl;  i++) {
//DBG(" - check ctrl=`d evnt=`d", evMap [i].ctrl, evMap [i].evnt);
       if ((ctrl == evMap [i].ctrl) && (evnt == evMap [i].evnt))
           {(ths->*(evMap [i].func)) (l);   return true;}
    }
    return false;
}

我不想关闭警告,因为那只是一种糟糕的形式。我尝试将 static_cast(0) 放在那里作为 0,但同样的警告。

我怎样才能使用这个讨厌的编译器继续生活?

【问题讨论】:

  • 0 是有符号整数。 0u 未签名。应该发生缩小,因为 0 是作为函数的地址提供的 - 而 int 在 64 位中是不够的。
  • @SergeyA 0 提供为 ctrl,而不是 func
  • 很确定是那些控制ID。它们似乎被定义为与 NM_FIRST 的偏移量,即 0u。 (见下面的答案)为什么?因为微软讨厌我。我不认为我使用的是 64 位,但我最好去检查一下。

标签: c++ visual-studio


【解决方案1】:

编译器警告的unsigned intIDC_LISTNM_CLICK,因为显然0 不是unsigned int

所以这两个中的任何一个都应该签名, ctrlevnt 应该是未签名的。

【讨论】:

  • 它们在我看来像整数...
     #define IDC_LIST 1076 #define NM_CLICK (NM_FIRST-2) // 使用 NMCLICK 结构 
    OH WAIT...
     #定义 NM_FIRST (0U- 0U) // 对所有控件通用 
    该死。看起来这可能会变得混乱。但至少我正在做一些事情......谢谢你,先生。
  • 啊。无法弄清楚如何格式化代码以挽救我的生命,但这是我的回答先生。微软将 NM_FIRST 定义为 0u 所以我有我的答案 - 谢谢。我希望这并不意味着太多的代码丑化,但我怀疑它确实......
猜你喜欢
  • 2021-01-02
  • 1970-01-01
  • 2020-06-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-10-05
  • 1970-01-01
相关资源
最近更新 更多