假设我有以下C代码.
unsigned int u = 1234;
int i = -5678;
unsigned int result = u + i;
Run Code Online (Sandbox Code Playgroud)
什么隐式转换在这里怎么回事,这是代码为安全的所有值u和i?(安全,从某种意义上说,即使此示例中的结果会溢出到某个巨大的正数,我也可以将其转换回int并获得真实的结果.)
我看到下面的代码行这里的C.
int mask = ~0;
Run Code Online (Sandbox Code Playgroud)
我已经打印了maskC和C++ 的值.它总是打印-1.
所以我确实有一些问题:
~0要为掩码变量赋值?~0什么?-1而不是~0吗?我正在一个我无法访问C++标准库的环境中编写C++代码,特别是不能访问std::numeric_limits.假设我想实施
template <typename T> constexpr T all_ones( /* ... */ )
Run Code Online (Sandbox Code Playgroud)
专注于无符号整数类型,我放在那里?具体来说,static_cast<T>(-1)够好吗?(根据我的猜测,我可以将其他类型视为无符号字符数组.)
比较无符号值时,如此测试:
if (pos == (size_t)-1)
Run Code Online (Sandbox Code Playgroud)
这种比较在技术上是否与以下类似:
if (pos == (size_t)~0)
Run Code Online (Sandbox Code Playgroud)
我不习惯第二种变体.这就是我问这个问题的原因.如果是的话,答案可能会相当直截了当.
请考虑以下代码:
template<bool> class StaticAssert;
template<> class StaticAssert<true> {};
StaticAssert< (-1 < sizeof(int)) > xyz1; // Compile error
StaticAssert< (-1 > sizeof(int)) > xyz2; // OK
Run Code Online (Sandbox Code Playgroud)
为什么是-1 > sizeof(int)真的?
-1提升到unsigned(-1)那时是真的吗unsigned(-1) > sizeof(int)?-1 > sizeof(int)相当于-1 > size_t(4)如果的sizeof(int)的是4,如果是这样的话,为什么-1 > size_t(4)是假的?这个C++标准是否合适?
我在这做错了什么?
$ cat size.c
#include<stdio.h>
#include<math.h>
int main() {
printf ("sizeof unsigned int = %d bytes.\n", sizeof(unsigned int));
printf ("sizeof unsigned long long = %d bytes.\n", sizeof(unsigned long long));
printf ("max unsigned int = %d\n", (int)(pow(2, 32) - 1));
printf ("max unsigned long long = %lld\n", (unsigned long long)(pow(2, 64) - 1));
}
$ gcc size.c -o size
$ ./size
sizeof unsigned int = 4 bytes.
sizeof unsigned long long = 8 bytes.
max unsigned int = 2147483647
max unsigned …Run Code Online (Sandbox Code Playgroud) 前几天,我遇到了这个结构:
static_cast<size_type>(-1)
Run Code Online (Sandbox Code Playgroud)
在一些示例C++代码中,可能(取决于where的详细信息size_type)等同于以下C:
(size_t)(-1)
Run Code Online (Sandbox Code Playgroud)
据我所知,它的工作原理是二进制补码算术中-1的表示形式,11111...1就像你所拥有的那样多,所以这是获得无符号类型size_t可以容纳的最大值的快速方法.但是,我的理解是C不保证将使用二进制补码; 如果C实现使用一个补码,这将比最大值小1,如果它使用有符号幅度,它将只是最大值的一半.
是否有一些我不知道的皱纹确保无论使用的有符号整数的表示如何都能正常工作?C和C++之间有什么不同(许多令人惊讶的事情都有)?
我偶尔会遇到一个整数类型(例如POSIX有符号整数类型off_t),其中有一个宏的最小值和最大值是有帮助的,但我不知道如何制作一个真正可移植的宏.
对于无符号整数类型,我一直认为这很简单.0最小和~0最大.我已经阅读了几个不同的SO线程,建议使用-1而不是~0为了便携性.这里有一个有争议的有趣线程:
c ++ - 使用-1将所有位设置为true是否安全?- 堆栈溢出
然而,即使在阅读了这个问题后,我仍然感到困惑.另外,我正在寻找兼容C89和C99的东西,所以我不知道是否适用相同的方法.说我有一种类型uint_whatever_t.难道我不能先转为0然后按位补码?这样可以吗?:
#define UINT_WHATEVER_T_MAX ( ~ (uint_whatever_t) 0 )
Run Code Online (Sandbox Code Playgroud)
有符号整数类型看起来像是一个更难以破解的坚果.我已经看到了几种不同的可能解决方案,但只有一种似乎是可移植的.无论是那个还是不正确的.我在谷歌搜索OFF_T_MAX和OFF_T_MIN时找到了它.感谢Christian Biere:
#define MAX_INT_VAL_STEP(t) \
((t) 1 << (CHAR_BIT * sizeof(t) - 1 - ((t) -1 < 1)))
#define MAX_INT_VAL(t) \
((MAX_INT_VAL_STEP(t) - 1) + MAX_INT_VAL_STEP(t))
#define MIN_INT_VAL(t) \
((t) -MAX_INT_VAL(t) - 1)
[...]
#define OFF_T_MAX MAX_INT_VAL(off_t)
Run Code Online (Sandbox Code Playgroud)
我找不到关于C89中不同允许类型的有符号整数表示的任何内容,但C99在§J.3.5中有关于整数可移植性问题的注释:
是否使用符号和幅度,二进制补码或一对补码表示有符号整数类型,以及非常值是陷阱表示还是普通值(6.2.6.2).
这似乎意味着只能使用那三个列出的签名数字表示.暗示是否正确,并且上面的宏是否与所有三种表示兼容?
MAX_INT_VAL_STEP()会给出不正确的结果.我想知道是否有任何办法解决这个问题.
通过维基百科上的带符号数字表示,我发现对于所有三个有符号整数表示,任何有符号整数类型的MAX都将是:
符号位关闭,所有值位开启(全部三个)
并且其MIN将是:
符号位开启,全部值符号打开(符号和幅度)
符号位打开,所有值位关闭(1 …
例如
size_t x = -1u;
if (x == -1u)
...
Run Code Online (Sandbox Code Playgroud)
有效?
如果这是有效的,它将阻止警告.当然在32位系统上x应该是0xffffffff而在64位系统上它应该是0xffffffffffffffff.
-Jochen
请考虑以下代码来设置x的所有位
unsigned int x = -1;
Run Code Online (Sandbox Code Playgroud)
这是便携式吗?它似乎至少适用于Visual Studio 2005-2010