- 注册时间
- 2007-12-26
- 最后登录
- 1970-1-1
- 威望
- 星
- 金币
- 枚
- 贡献
- 分
- 经验
- 点
- 鲜花
- 朵
- 魅力
- 点
- 上传
- 次
- 下载
- 次
- 积分
- 92615
- 在线时间
- 小时
|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?欢迎注册
×
有符号的大整数加减法,最终都会进行无符号的加减法。
而无符号的减法,必须得是较大者作为被减数,也就是说得先有个比较运算。
而就是这一步,曾害得我花了好几个小时去排查一个 bug,最终居然是微软编译器的问题!
- // test.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
- //
- #include "pch.h"
- #include <compare>
- #include <iostream>
- // 2020-03-16, gxqcn 发现编译器 bug: 如写成 const auto cmp{ *--pl <=> *--pr }, 当 0 != cmp 时,指针会多移动一次!
- int main()
- {
- const auto test{ []( auto a, auto b )
- {
- std::cout << "before compare: a=" << a << " b=" << b << "\n";
- const auto cmp{ a++ <=> b++ };
- std::cout << "after compare: a=" << a << " b=" << b << "\n\n";
- // 为了对比检测 std::max() 是否有类似表现,
- std::cout << "std::max( a++, b++ ) = " << std::max( a++, b++ ) << "\n";
- std::cout << "after std::max: a=" << a << " b=" << b << "\n\n";
- }};
- test( 1, 1 ); // 测试表明:当相等时,表现与预期相符
- test( 1, 2 ); // 测试表明:当不等时,表现与预期不符
- std::cout << "-------------------------\n\n";
- int v1[]{ 1, 2, 3, 4, 5, 6 };
- int v2[]{ 1, 2, 0, 9, 0, 6 };
- auto p1{ std::cbegin( v1 ) - 1 };
- auto p2{ std::cbegin( v2 ) - 1 };
- std::cout << "compare: v1{ 1, 2, 3, 4, 5, 6 } <=> v2{ 1, 2, 0, 9, 0, 6 }\n\n";
- for ( auto index{ 0 }; sizeof( v1 ) / sizeof( v1[ 0 ] ) != index; ++index )
- {
- if ( const auto cmp{ *++p1 <=> *++p2 }; 0 != cmp )
- {
- std::cout << "v1[" << index << "] = " << v1[ index ] << "; *p1 =" << *p1 << "\n";
- std::cout << "v2[" << index << "] = " << v2[ index ] << "; *p2 =" << *p2 << "\n";
- if ( 0 < cmp )
- {
- std::cout << "\nv1 > v2";
- }
- else
- {
- std::cout << "\nv1 < v2";
- }
- if (( v1[ index ] <=> v2[ index ] ) == cmp )
- {
- std::cout << ", it's right.\n\n";
- }
- else
- {
- std::cout << " ?! it's wrong!!\n\n";
- }
- break;
- }
- }
- system( "pause" );
- }
复制代码
注意:需在 属性页->常规->C++语言标准 中设定“预览 - 最新 C++ 工作草案中的功能 (std:c++latest)”才能编译
其运行结果如下:
- before compare: a=1 b=1
- after compare: a=2 b=2
- std::max( a++, b++ ) = 2
- after std::max: a=3 b=3
- before compare: a=1 b=2
- after compare: a=3 b=4
- std::max( a++, b++ ) = 4
- after std::max: a=4 b=5
- -------------------------
- compare: v1{ 1, 2, 3, 4, 5, 6 } <=> v2{ 1, 2, 0, 9, 0, 6 }
- v1[2] = 3; *p1 =4
- v2[2] = 0; *p2 =9
- v1 < v2 ?! it's wrong!!
- 请按任意键继续. . .
复制代码
这个 bug 不仅是运算结果不对的问题,还有导致指针越界的风险,
解决的方式是:在 <=> 两端,尽量避免自增/自减等运算,
不过这只是避坑而已,坑仍在那里!
这个 bug 是昨天上午发现的,当时版本是 VS2019 16.4.6;
今早微软对它进行了更新,版本为 16.5.0;
但刚才测试了下,该 bug 依然存在。 |
|