所以,我们都知道C/C++有符号/无符号比较规则-1 > 2u == true,我有一种情况,我希望有效地实现'正确'的比较.
我的问题是,考虑到人们熟悉的众多架构,这样做更有效率.显然英特尔和ARM的权重更高.
鉴于:
int x;
unsigned int y;
if (x < y) {}
Run Code Online (Sandbox Code Playgroud)
推广是否更好:
x < y => (int64)x < (int64)y
Run Code Online (Sandbox Code Playgroud)
或者更好地进行2次比较,即:
x < y => (x < 0 || x < y)
Run Code Online (Sandbox Code Playgroud)
前者意味着零扩展,符号扩展和一个比较+分支,后者不需要符号扩展操作,而是需要2个连续的cmp +分支.
传统智慧认为分支比符号扩展更昂贵,这将是管道,但在第一种情况下扩展和单一比较之间存在停滞,而在第二种情况下,我可以想象一些架构可能会对这两种比较进行管道传输. ,然后是2个条件分支?
存在另一种情况,其中无符号值是比带符号类型更小的类型,这意味着可以使用单个零扩展到有符号类型的长度,然后进行单个比较...在这种情况下,它更可取使用extend + cmp版本,还是2比较方法仍然是首选?
英特尔?臂?其他?我不确定这里是否有正确的答案,但我希望听到人们的回答.如今,低水平的性能很难预测,特别是在英特尔和ARM上越来越多.
编辑:
我应该补充一点,有一个明显的解决方案,其中类型的大小等于体系结构的宽度; 在这种情况下,显然2比较解决方案是优选的,因为促销本身不能有效地执行.显然,我的int示例满足32位体系结构的这种条件,您可以将思想实验转换short为适用于32位平台的练习.
编辑2:
对不起,我忘了u在-1 > 2u!> _ <
编辑3:
我想修改这种情况,假设比较的结果是一个实际的分支,结果不是作为布尔值返回的.这就是我喜欢的结构外观; 虽然这确实提出了一个有趣的观点,即当结果是bool与分支时,存在另一组排列.
int g;
void fun(int x, unsigned in y) { if((long long)x < (long …Run Code Online (Sandbox Code Playgroud) 使用VS2010构建,我正在构建一个导致许多链接错误的库:
error LNK2038: mismatch detected for '_ITERATOR_DEBUG_LEVEL': value '0' doesn't match value '2'
Run Code Online (Sandbox Code Playgroud)
导致我必须同时发布我的lib的发行版和调试版.我没有理由发布lib的调试版本,它只是膨胀二进制发行版.但是内置调试的客户端代码拒绝链接我的发布库.
我之前看到过这个问题,但他们似乎并未提出正确的问题.我理解这个错误是什么,为什么我得到它(好吧,有点;我不确定是什么发出依赖.你呢?),但我想知道的是如何消除这种依赖性的发生在我的lib?
类似于在使用冲突的CRT时抱怨的libs,可以使用/ Zl(从目标文件中省略默认库名)来防止,当然有一种方法可以防止这种依赖性也被发送到我的libs中吗?
我只想生成一个优化的lib,它能够链接到调试或发布代码.客户端代码调试lib并不重要.几乎没有第三方库提供不同的调试和发布版本.供应商如何避免这个问题呢?
有没有人知道究竟是什么原因导致这种链接依赖,以及如何完全禁用它,或将其从我的代码中分解出来?
刚刚安装了VS2017,声称自2015年以来拥有出色的C++ 14支持(这是初步的).给我的一个项目使用了一个旋转constexpr,并注意到似乎是一些回归.
这段代码:
struct s
{
size_t i;
constexpr s(nullptr_t) noexcept : i(0) {}
};
static_assert(s(nullptr).i == 0, "!!");
Run Code Online (Sandbox Code Playgroud)
在VS2015和Clang上编译没问题,但我在VS2017中遇到一个新错误:
error C2131: expression did not evaluate to a constant
note: failure was caused by unevaluable pointer value
note: while evaluating 's::s(&s{(null)})'
Run Code Online (Sandbox Code Playgroud)
这段代码看起来不错吧?是否constexpr有问题nullptr?
我很惊讶这个基本可能出现的回归,我怀疑我的代码一定有问题......
为什么Microsoft Visual C++在编译以下代码时失败?:
template <typename T>
struct slice
{
size_t length;
T *ptr;
constexpr slice(std::initializer_list<T> list)
: length(list.size()), ptr(list.begin()) {}
};
static_assert(slice<const int>({ 1, 2, 3 }).length == 3, "!!");
Run Code Online (Sandbox Code Playgroud)
我得到的错误是:
1>test.cpp(12): error C2131: expression did not evaluate to a constant
1> visual studio 14.0\vc\include\initializer_list(50): note: failure was caused by an undefined arithmetic operation
Run Code Online (Sandbox Code Playgroud)
initializer_list所有方法的实现都标记了constexpr,看起来它对我来说应该没问题......也许它只是一个编译器问题?