惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
Spread Privacy
Spread Privacy
T
Troy Hunt's Blog
Recent Announcements
Recent Announcements
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
S
Schneier on Security
罗磊的独立博客
T
The Exploit Database - CXSecurity.com
博客园 - 司徒正美
月光博客
月光博客
C
Cybersecurity and Infrastructure Security Agency CISA
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
Project Zero
Project Zero
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
Latest news
Latest news
L
Lohrmann on Cybersecurity
阮一峰的网络日志
阮一峰的网络日志
C
CERT Recently Published Vulnerability Notes
腾讯CDC
Jina AI
Jina AI
Cyberwarzone
Cyberwarzone
T
Threat Research - Cisco Blogs
T
Tenable Blog
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
博客园 - Franky
宝玉的分享
宝玉的分享
WordPress大学
WordPress大学
Attack and Defense Labs
Attack and Defense Labs
C
Cyber Attacks, Cyber Crime and Cyber Security
V
V2EX
T
Tailwind CSS Blog
有赞技术团队
有赞技术团队
Scott Helme
Scott Helme
小众软件
小众软件
L
LINUX DO - 最新话题
博客园 - 叶小钗
博客园 - 【当耐特】
PCI Perspectives
PCI Perspectives
SecWiki News
SecWiki News
S
Security Affairs
P
Palo Alto Networks Blog
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
S
SegmentFault 最新的问题
Recent Commits to openclaw:main
Recent Commits to openclaw:main
博客园 - 聂微东
量子位
C
CXSECURITY Database RSS Feed - CXSecurity.com
Help Net Security
Help Net Security
S
Secure Thoughts
S
Securelist

Shiroha白羽的博客

Golang 踩坑 —— interface 为参数的时候传 nil 指针 Codeforces Round 925 (Div. 3) Codeforces Round 924 (Div. 2) Codeforces Round 923 (Div. 3) Codeforces Round 922 (Div. 2) Codeforces Round 921 (Div. 2) Educational Codeforces Round 161 (Rated for Div. 2) Codeforces Round 920 (Div. 3) Codeforces Round 919 (Div. 2) Hello 2024 Good Bye 2023 Codeforces Round 918 (Div. 4) 个人备份的常用 macOS 清理命令 Codeforces Round 917 (Div. 2) Pinely Round 3 (Div. 1 + Div. 2) Educational Codeforces Round 160 (Rated for Div. 2) Codeforces Round 915 (Div. 2) Codeforces Round 914 (Div. 2) Codeforces Round 913 (Div. 3) Educational Codeforces Round 159 (Rated for Div. 2) Codeforces Round 912 (Div. 2) Codeforces Round 911 (Div. 2) CodeTON Round 7 (Div. 1 + Div. 2, Rated, Prizes!) Educational Codeforces Round 158 (Rated for Div. 2) Codeforces Round 910 (Div. 2) Codeforces Round 909 (Div. 3) Codeforces Round 908 (Div. 2) Educational Codeforces Round 157 (Rated for Div. 2) C++自定义的字面量 Codeforces Round 907 (Div. 2) Codeforces Round 916 (Div. 3) 关于 LRU map 的一些灵感 2023 杭州站 ICPC 现场赛 反复横跳的 Clang-Tidy(cert-dcl21-cpp) Codeforces Round 906 (Div. 2) Codeforces Round 905 (Div. 3) Codeforces Round 904 (Div. 2) Codeforces Round 903 (Div. 3) Educational Codeforces Round 156 (Rated for Div. 2) Codeforces Round 902 (Div. 2, based on COMPFEST 15 - Final Round) Codeforces Round 901 (Div. 2) Codeforces Round 900 (Div. 3) Codeforces Round 899 (Div. 2) Educational Codeforces Round#155 (Div. 2) Codeforces Round 898 (Div. 4) CodeTON Round 6 (Div. 2) Codeforces Round 897 (Div. 2) Codeforces Round 896 (Div. 2) Codeforces Round 887 (Div. 2) Codeforces Round 895 (Div. 3) 左值-右值-将亡值 blog.mauve.icu Pinely Round 2 (Div. 1 + Div. 2) Harbour.Space Scholarship Contest 2023-2024 (Div. 1 + Div. 2) Codeforces Round 894 (Div. 3) Codeforces Round 888 (Div. 3) Educational Codeforces Round#153 (Div. 2) Codeforces Round 893 (Div. 2) OTPAUTH,两步验证中的通用协议 Codeforces Round 892 (Div. 2) Codeforces Round 891 (Div. 3) Codeforces Round 890 (Div. 2) Educational Codeforces Round#152 (Div. 2) blog.mauve.icu Java Script 的 null 和 undefined 随想 记一次 SQL LEFT JOIN 没有得到预期结果的错误 Codeforces Round#789(Div. 2) GCC/G++ 预编译头性能优化 使用 Junit5 和 Mockito 实现 SpringBoot 的单元测试最优美的解决方案 centOS 防火墙 docker-compse 的问题 C++ 语言实现动态变化的线程池 Codeforces Round#744 (Div. 3) 计算机图形学 Windows 通过网络访问 WSL2 原生 JavaScript 实现图片裁剪 面试复习(计算机图形学) 面试复习(算法) Codeforces Round#706(Div. 2)-Let's Go Hiking 面试复习(Java) 面试复习(Git) 面试复习(Linux) 面试复习(数据库) 面试复习(计算机网络) 面试复习(操作系统) 面试复习(C++) Codeforces Round#699 (Div. 2) 清理 WSL2 的磁盘占用 Codeforces Round#697 (Div. 3) Windows 下的 NTFS 驱动器索引 BUG 计算机网络复习 记一次 Navicat 连接 MySQL 一直报认证错误(Access denied) 计算机网络实验复习 WSL1 使用 Docker 一直无法启动 我的ACM脚印 2020牛客暑期多校训练营(第三场)D-Points Construction Problem——构造 2020牛客暑期多校训练营(第三场)E-Two Matchings——复杂思维与简单dp 2020牛客暑期多校训练营(第二场)I-Interval——最大流转对偶图求最短路 Educational Codeforces Round 80 D. Minimax Problem——二分+二进制处理 Codeforces Round 606 E. Two Fairs——图论 Codeforces Round 612 (Div. 2) C. Garland——DP
一段奇怪的 CPP 代码
Shiroha · 2023-12-03 · via Shiroha白羽的博客

最近发现了一个奇怪的代码,在 C++17 下。使用的 cmake 命令是

1
"~/Applications/CLion Nova.app/Contents/bin/cmake/mac/aarch64/bin/cmake" -DCMAKE_BUILD_TYPE=Debug "-DCMAKE_MAKE_PROGRAM=~/Applications/CLion Nova.app/Contents/bin/ninja/mac/aarch64/ninja" -G Ninja -S ~/Code/ClionProject -B ~/Code/ClionProject/cmake-build-debug

而这段代码则是

1
2
3
4
5
list<int> l;
for (int i = 0; i < 10; ++i) l.push_back(i);
auto iter = l.begin();
for (int i = -1; i >= -10; --i) l.insert(iter--, i);
for (int&v: l) cout << v << ' ';

这段代码的结果却是

1
-1 0 1 -10 2 -9 3 -8 4 -7 5 -6 6 -5 7 -4 8 -3 9 -2 

如果稍微调整一下,比如这样的代码

1
2
3
4
5
6
7
8
list<int> l;
for (int i = 0; i < 10; ++i) l.push_back(i);
auto iter = l.begin();
for (int i = -1; i >= -10; --i) {
l.insert(iter, i);
--iter;
}
for (int&v: l) cout << v << ' ';

得到的结果却是

1
-10 -9 -8 -7 -6 -5 -4 -3 -2 -1 0 1 2 3 4 5 6 7 8 9 

如果调整成这样

1
2
3
4
5
6
7
8
list<int> l;
for (int i = 0; i < 10; ++i) l.push_back(i);
auto iter = l.begin();
++iter;
for (int i = -1; i >= -10; --i) {
l.insert(--iter, i);
}
for (int&v: l) cout << v << ' ';

得到的结果也是

1
-10 -9 -8 -7 -6 -5 -4 -3 -2 -1 0 1 2 3 4 5 6 7 8 9 

这似乎有点不太符合预期。至少后两个是符合预期的,而第一个就有点奇怪了。第一反应是不是踩到 UB 了,但是很快在文档里找到了不符合预期的描述

docs

既然如此,那么就写一段测试代码看看

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
list<int> l;

void f(list<int>::iterator iter, int v) {
cout << *iter << ' ';
l.insert(iter, v);
cout << *iter << endl;
}

void solve() {
for (int i = 0; i < 10; ++i) l.push_back(i);
auto iter = l.begin();
for (int i = -1; i >= -10; --i) {
f(iter--, i);
cout << (iter == l.begin()) << endl;
for (int&v: l) cout << v << ' ';
cout << endl;
}
}

此处进行了一下代理,将每次试图写入钱,通过 f 函数进行代理后,再执行插入操作。结果发现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
0 0
0
-1 0 1 2 3 4 5 6 7 8 9
11 12
0
-1 0 1 2 3 4 5 6 7 8 9 -2
9 9
0
-1 0 1 2 3 4 5 6 7 8 -3 9 -2
8 8
0
-1 0 1 2 3 4 5 6 7 -4 8 -3 9 -2
7 7
0
-1 0 1 2 3 4 5 6 -5 7 -4 8 -3 9 -2
6 6
0
-1 0 1 2 3 4 5 -6 6 -5 7 -4 8 -3 9 -2
5 5
0
-1 0 1 2 3 4 -7 5 -6 6 -5 7 -4 8 -3 9 -2
4 4
0
-1 0 1 2 3 -8 4 -7 5 -6 6 -5 7 -4 8 -3 9 -2
3 3
0
-1 0 1 2 -9 3 -8 4 -7 5 -6 6 -5 7 -4 8 -3 9 -2
2 2
0
-1 0 1 -10 2 -9 3 -8 4 -7 5 -6 6 -5 7 -4 8 -3 9 -2

仍然有这个奇奇怪怪的问题。

正当我想要搜索一些文档来看看是不是什么奇奇怪怪的 bug 的时候,突然意识到一个问题:i++; 等价于下面这三行代码

1
2
3
auto tmp = i;
++i;
return tmp;

这似乎就能解释为什么了!因为在试图进行 iter-- 操作的时候,又进行了插入操作,实际上导致了 iter 本身先移动到了前一个指针的位置,而在 STL 标准库实现的 list 中,这个链表是一个双向带头循环链表,故实际上此时 iter 是先被移动到了 end() 的位置,然后再返回了 begin() 的位置,并在 begin() 前插入了一个值,使得实际上的 begin() 发生了更新。而实际上我们的 iter 早就被移动到 end() 的位置。