C/C++;有符号/无符号整数和函数调用的最佳实践 我问这个问题是用两种不同的语言:C和C++。< /P>

C/C++;有符号/无符号整数和函数调用的最佳实践 我问这个问题是用两种不同的语言:C和C++。< /P>,c++,c,C++,C,当调用与我们在代码中要求的整数符号期望相反的函数时,最佳实践是什么 例如: uint32 _depth; // uint32 = DWORD int depth; _BitScanForward(&_depth, (uint32)input); // DWORD, DWORD depth = (int)_depth; _BitScanForward需要DWORD(uint32)参数。变量input是in

当调用与我们在代码中要求的整数符号期望相反的函数时,最佳实践是什么

例如:

uint32       _depth;                        // uint32 = DWORD
int          depth;

_BitScanForward(&_depth, (uint32)input);    // DWORD, DWORD
depth = (int)_depth;
_BitScanForward需要DWORD(uint32)参数。变量
input
是int16类型,我需要在代码中将结果
\u depth
作为int32进行处理

  • 我是否需要关心如图所示的强制转换
    输入
    ?我知道编者可能会为我做这件事,但最佳实践是什么
  • 是否可以将
    \u depth
    声明为int32,从而避免以后如图所示强制转换它
  • 注意:

    我对编者的评论是基于经验的。我编写的代码在VS中编译时没有警告,但在执行时崩溃。事实证明,我调用的是一个具有不正确宽度int的函数。所以我不再把这个话题留给编译器了

    编辑:


    答案很有用,谢谢。让我完善我的问题。如果没有宽度问题,即函数不希望int比传入的更窄(显然会失败),那么依靠编译器处理符号和宽度差异可以吗?

    这取决于您的使用情况等:

    如果我能使用需要的类型,我就使用类型

    如果没有: 当您隐式转换可能导致溢出/下溢的数据类型时,编译器应该向您发出警告。因此,我通常会打开这些警告,并将隐式转换更改为显式转换

    在这里,我有两种不同的方法:

    如果我100%确信我从未超出/低于有符号/无符号int之间的边界,我将使用
    静态\u cast
    。(通常用于转换不同的API,比如返回int和size\t的size()

    当我不确定或可能不确定时,我会使用
    boost::numeric\u cast
    。当您超出边界进行强制转换时,这会引发异常,从而显示何时发生这种情况


    例外情况下的方法遵循的做法是,如果出现问题,则硬失败/崩溃/终止,而不是继续使用损坏的数据,然后在其他地方崩溃,或者使用未定义的数据执行其他操作。

    我强烈建议将该函数隐藏到与首选API一致的自定义包装函数中(并在此函数中执行适当的显式转换)。在使用特定于编译器的函数的情况下,这还有一个额外的优点,即将其移植到不同的编译器会更容易(如果您希望这样做的话),只需重新实现包装器函数。

    首先,编译器将使强制转换隐式化,并在任何有意义的警告级别上向您发出警告


    您执行的两种类型转换都是编译器(或您的同事)无法轻松确定其是否正确的类型转换,因此使用边界测试进行显式类型转换或显式转换是最佳做法。您选择哪种类型取决于您对数据的了解。最安全的方法是检查边界条件。最便宜的方法是简单地进行类型转换(C++中请使用STATICE-CAST非C型铸件)当从小于
    int
    的任何整数类型转换为宽度等于或大于
    int
    的任何整数类型时,编写显式转换非常重要。如果不这样做,编译器将首先将值转换为
    int
    ,因为“整数提升”规则,然后是目标类型。这几乎总是错误的,如果我们今天从零开始,我们不会以这种方式设计语言,但为了兼容性,我们不得不使用它


    系统提供了类型代码: UTIN16GYT, UTIN32×T<<代码>, Word , dWord < /C> >可能比C++ > INT/COM>更窄、更宽,或相同大小;在C++中,可以使用模板来解决它,但是在C中您不能。因此,您可能需要为涉及这些的任何转换编写明确的转换。

    “我可以把深度作为It32声明吗?”“有什么能阻止你这么做吗?”“大概是你做的吧?你用哪种语言?C还是C++?这是两种截然不同的语言。选一个!”丹尼尔达拉娜定义“可以”=“用来表示能力或许可”。许可在接受中。但是我只是为你改变了我的问题;请一次只问一种语言。如果你所说的每种语言的答案都不一样,那会把事情搞得一团糟!当然你实际上使用的是一种或另一种语言,所以只需说出那一种。这是一个很好的库间操作解决方案。好主意!我不清楚为什么我的强制转换对编译器/人类来说是不清楚的。请explain。编译器始终不清楚从有符号到无符号的第一次强制转换。因为它不知道有符号变量是负数还是正数。第二次强制转换为无符号到有符号。在此,编译器无法确定无符号int的值是否大于最大有符号值。因此,它必须警告您。您的同事们也有同样的问题。如果只看一小部分代码,他们就不能做出决定,如果你做的是正确的事情,那么,IAM:通过使用C++ <代码> RealTytRease你会告诉源代码级别,你想使用和U[]相同的位模式。int,比如从
    int32_t-1
    uint32_t 0xFFFFFFFF
    的值。Reinterpret_cast不会编译为任何指令,它只是源代码级别的值类型更改。如果您有一些设计糟糕的API,例如返回
    int size()
    ,但它决不是要返回负数等。总的来说,最好的做法当然是避免任何转换,并始终使用正确的类型,在其他情况下是cast+test。@IamIC the C