The True Placeholder Symbol in C++

In many programming language, the common way to indicate that the symbol is not important, is to use _ for the symbol.

It was just a convention in C++, but it will become a language feature start from C++26.

Well… what’s the difference?


We use _ when there is some declaration but we do not care the name / have no good name for the variable.

For example, a common trick to preserve the life time of RAII lock is

1
2
3
4
5
void doJob() {
static std::mutex mutex;
std::lock_guard _(mutex); // give it a name so it won't unlock immediately
// some jobs ...
}

Or in structure-binding statement.

1
2
3
4
5
6
7
8
template <std::regular T>
std::tuple<T, bool> someJob() {
return { {}, true };
}

void foo() {
auto [_, done] = someJob<int>();
}

The problem is… in C++, this style is just a convention, _ is still a regular variable. So if we want to ignore two value with different type, it does not work since the type mismatch.

1
2
3
4
5
void foo() {
auto [_1, done1] = someJob<int>();
auto [_2, done2] = someJob<std::string>();
// we need to separate _2 from _1
}

That’s frustrating, especially for people with experience of pattern-matching expression in other languages.

So in C++26 (proposed by P2169), now we can new way to interpret the semantic of _.

The rule is simple.

If there is only one declaration of _ in some scope, everything is same as before.

A we can reference it later if we wan’t, although it’s probably a bad smell to use _ in this case.

If there are more declarations of _, they all refer to different objects respectively.

In this case, they can only be assigned to. Try to use them is a compiling error.

And we can finally write something that looks more natural.

1
2
3
4
void foo() {
auto [_, done1] = someJob<int>();
auto [_, done2] = someJob<std::string>();
}

Golang has this feature from the beginning, is called blank identifier. For Python, although being a dynamic-type language, there is no problem to do use _ for different type value. _ is defined as a wildcard when pattern-matching is introduced to Python (PEP 634).

It’s happy to see this came to C++ now. :D

Google 更新 Go 的社群行為準則

昨天 Go blog 上出新文章,說要更新 Code of Conduct。

一直一來覺得每個社群的 CoC 都寫得差不多,不外乎是要互相尊重、開放透明、建設性發言等等。 也因為都差不多,平常也不會去細看。反正就是些正常人該有的道德觀。 因此,看到說要更新 Code of Conduct 讓我感到有點好奇。

讀一讀讀下去,其實這次 Go community 的 CoC 就是新增一條:

Be responsible. What you say and do matters. Take responsibility …

沒想到連這個都要寫進 CoC …。可能 Go 的核心開發團隊看 issue 真的看到心累了? XD

See: Code of Conduct Updates - go.dev

GitLab 更換自家 GPG Key

今天 GitLab 在自家 blog 上公告 revoke 簽署 package 的 GPG key。

We recently became aware of an instance where this key and other tokens used to distribute official GitLab Runner packages and binaries were not secured according to GitLab’s security policies.

We have not found any evidence of unauthorized modification of the packages or access to the services storing them.

並不是因為 key 被 compromise,僅是因為 key 不符合公司的安全規範,所以就進行了一次 rekey。

GPG key rekey 並不如換憑證一樣,只要重簽一張就好 (因為信賴建立在已知的第三方 CA 上)。 GPG key rekey 需要透過可信管道重新宣告 fingerprint 並請大家 import 新的 key。 這個轉換的成本,相較換憑證應是高非常多且難以量化的。

沒想到居然僅為了不合安全規範就進行 rekey,不愧是國際一線的軟體公司!

See: The GPG key used to sign GitLab Runner packages has been rotated | GitLab

VS Code 新功能: Remote Repositories

VS Code 在 1.57 版中, Remote Development 系列 extension 加入了新成員: Remote Repositories

有了這個 extension 之後,如果遇上臨時想看的 project,就可以直接在 VS Code 中叫出來看,不需要事先 clone 至某個 local 資料夾。

不過.. 因為這個 extension 實際上是建一個 Virtual Workspaces 並把 code 放在裡面閱覽, 所以用 Remote Repositories 開出來的 workspace 功能非常受限。 諸如 Debug, Terminal 及大部分的 extension 基本上都不能用。 但話雖如此,當看 code 看一看想要開始進行比較深入的修改及除錯時, 其實也是有提供轉換成一般 workspace 的功能。 使用上非常方便!

可惜的是,目前此 extension 支援的 remote repository 種類只有 GitHub。 且如同其他 Remote Development Series,這個 extension 並非 open source project:

未來會不會支援 GitHub 以外的 Git repositories,甚至其他種類的 VCS, 只能看微軟爸爸的眼色了。