yohhoyの日記

技術的メモをしていきたい日記

リテラル0との比較のみ許容する型

リテラル0との比較のみ許容する型の作り方。そのような型として、C++2a(C++20)三方比較演算子<=>の戻り値型(partial_ordering/ weak_ordering/strong_ordering)がある。 // C++2a #include <cassert> #include <compare> int main() { std::strong_ordering r = (108 <=> 42); </compare></cassert>…

requires式から利用可能な宣言

C++2a(C++20) コンセプト requires式(requires-expression) では、同式を包含するコンテキストのあらゆる宣言を利用できる。下記コードのrequires式からは関数テンプレートの仮引数xを参照している。requires式の本体(requirement-body)は評価されず(unevalu…

ラムダ式のオーバーロード

プログラミング言語C++において、ラムダ式のオーバーロード(もどき)を実装する方法。 // C++17 template <typename... Ts> struct overloaded : Ts... { // 基底クラス(ラムダ式のクロージャクラス)が提供する // operator()群をoverloadedクラス自身から公開する using </typename...>…

yield式を使わないジェネレータ

C++2a(C++20)コルーチンにはジェネレータ実装を容易にするco_yield式が導入されるが、動作仕様的にはco_await式のシンタックスシュガーとなっている。 #include <coroutine> #include <iostream> #include <utility> #define MIMIC_CO_YIELD 1 #if MIMIC_CO_YIELD // yield式相当を表現する</utility></iostream></coroutine>…

C++20標準ライブラリ仕様:Constraints/Mandates/Preconditions

C++2a(C++20)標準ライブラリの関数仕様記述で用いられる Constraints/Mandates/Preconditions の違いについてメモ。 現行C++17標準ライブラリの Requires は廃止され、C++2aでは Constraints/Mandates/Preconditions に細分化される。 Mandates: 型や定…

atoi関数のかしこい実装

C

C標準ライブラリ Muslのatoi関数実装 では、符号付き整数オーバーフロー回避のため負数範囲で10進数値を減算してゆき最後に符号反転を行っている。 int atoi(const char *s) { int n=0, neg=0; while (isspace(*s)) s++; switch (*s) { case '-': neg=1; cas…

関数型への参照型にまつわる特例ルール

C++

プログラミング言語C++の関数型(function type)には左辺値(lvalue)しか存在しないが(→id:yohhoy:20200530)、左辺値参照型(R (&)(Args...))/右辺値参照型(R (&&)(Args...))いずれにも束縛できる。そう、よかったね。 #include <utility> using std::move; // 右辺値</utility>…

関数型の右辺値は存在しない

C++

プログラミング言語C++に「関数型(function type)の右辺値(rvalue)」は存在しない。関数型をもつ式の value category は常に左辺値(lvalue)となる。だから何? int v; struct S s; void f(); std::move(v); // xvalue std::move(s); // xvalue std::move(f);…

C2x標準の属性(attribute)

C C2x

プログラミング言語Cの次期仕様C2xでは 属性(attribute) 構文が標準化される。属性構文を先行導入したC++言語とほぼ等価であり、連続するブラケット[[/]]を用いる。*1 // C2x [[nodiscard]] int f(); void g([[maybe_unsed]] int a) { [[maybe_unused] int …

コンストラクタ/デストラクタ×仮想関数呼び出し

C++においてコンストラクタ/デストラクタからの仮想関数呼び出しそれ自体はwell-definedだが、おそらくC++プログラマの期待する振る舞いではない。バグの温床になりえるため、大抵のコーディング規約で禁止している(はず)。かつてClangに本件を検知する警…

macOSはPOSIX無名セマフォをサポートしない

macOS(旧Mac OS X)では POSIX無名(unnamed)セマフォ を意図的にサポートしない。 無名セマフォ生成sem_initや破壊sem_destroy関数呼び出しはerrno=ENOSYS(function not supported)/戻り値-1で常に失敗する。(おまけ:sem_getvalue関数も非サポート)名前…

Objective-C的 null(nil)安全

Objective-Cにおいてメッセージ送信先のレシーバがnilの場合、Objective-Cランタイムはなにもしない(エラーは発生せずメソッドも呼び出されない)。メソッドが戻り値型を持つ場合、値 0 相当が返却されたかのように振る舞う。 Sending Messages to nil In O…

電子書籍"A Heavily Commented Linux Kernel Source Code"

初期のLinuxカーネル(Version 0.12)ソースコード詳細解説と図解を試みる電子書籍。1109ページの超大作。 http://www.oldlinux.org/ (PDF) "A Heavily Commented Linux Kernel Source Code," Zhao Jiong

単一メンバunionの使い道

C++

プログラミング言語C++において、単一メンバしか含まない共用体(union)を用いるとオブジェクトの明示的な生成/破棄操作が可能となる。貧者(poor man's)のOptional。 #include <iostream> template <typename T> union Wrapper { // 共用体Uのコンストラクタ/デストラクタ定義は必</typename></iostream>…

名前によるUnicodeリテラル表現

PythonではUnicodeコードポイントによるリテラル表現*1の他に、Unicode文字データベース(UCD; Unicode Character Database)*2に準じた名前表現もサポートする。 print("\U0001F4DB") # print("\N{NAME BADGE}") # print("\N{TOFU ON FIRE}") # SyntaxError…

Go言語の++/--は文(Statement)

Go

Go言語におけるインクリメント++/デクリメント--演算子は、後置(postfix)記法のみが許容され、式(expression)ではなく 文(statement) を構成する。 i++; // i += 1; と等価 i--; // i -= 1; と等価 Why are ++ and -- statements and not expressions? And …

独自診断メッセージ diagnose_if属性

Clangコンパイラはユーザ定義のコンパイル警告/エラーメッセージ出力を行うdiagnose_if属性を提供する。 The diagnose_if attribute can be placed on function declarations to emit warnings or errors at compile-time if calls to the attributed funct…

電子書籍"Modern C (2nd Ed.)"

C

最新C17までカバーした、モダンなC言語プログラミングに関する電子書籍。PDF形式(315頁)はCC BY-NC-ND 4.0ライセンス。 https://modernc.gforge.inria.fr/ , Jens Gustedt https://gustedt.wordpress.com/2019/09/18/modern-c-second-edition/

イテレータに->演算子オーバーロードは必要?

C++標準ライブラリが定める InputIterator 要件(requirement) と input_iteratorコンセプト(concept) の変遷についてメモ。まとめ: C++2a(C++20) input_iteratorコンセプトではイテレータ型にoperator*オーバーロードのみ要求する。operator->オーバーロー…

same_asコンセプトとSymmetric Subsumption Idiom

C++2a(C++20)ライブラリ提供の標準コンセプトstd::same_as、およびコンセプト定義における対称包摂イディオム(Symmetric Subsumption Idiom)についてメモ。制約式std::same_as<X, Y>と制約式std::same_as<Y, X>は対称関係、つまり互いに一方が他方を包摂する(subsume)関</y,></x,>…

20分くらいでわかった気分になれるC++20コルーチン

20分くらいでわかった気分になれるC++20コルーチン本文こちら→C++ MIX #5に参加しました - yohhoyの日記(別館)スライド資料:https://www.slideshare.net/yohhoy/20c20 関連URL C++コルーチン拡張メモ(N4736) - yohhoyの日記 C++コルーチン拡張メモ - Qi…

コンセプト制約式の包摂関係とオーバーロード解決

C++2a(C++20)で導入されるコンセプト(concept)に関して、制約式(constraint-expression)間の包摂(subsume)ルールに基づくオーバーロード解決のメモ。本記事の内容はStackOverflowで見つけた質問と回答に基づく。要約:制約式の包摂関係(subsumption relation…

va_argマクロの奇妙な制限事項

C言語の可変引数リストアクセス用 va_arg マクロにおける奇妙な制限事項についてメモ。va_argマクロの第二引数へ指定する型名には、“関数ポインタ型” や “配列へのポインタ型” を直接記述できない。ただしtypedefによる別名であればOK。こんなコード書くやつ…

C++標準コンセプトの名前付けガイドライン

C++2a(C++20)標準ライブラリに導入される コンセプト(concept) の名前付けガイドラインについて。2019年Cologne会合にて (PDF)P1754R1 が採択され、Ranges TS提案当初から PascalCase 形式で検討されていた命名規則から snake_case 形式へと変更された。これ…

フライングWindows API待機関数

Windows APIのタイムアウト指定待機関数では、指定期間よりも僅かに早くタイムアウト発生する。この振る舞いは仕様通り(by design)とのこと。 WaitForSingleObject, WaitForSingleObjectEx WaitForMultipleObjects, WaitForMultipleObjectsEx MsgWaitForMult…

nan("is Not-a-Number")

C C++

プログラミング言語C/C++における浮動小数点数 NaN(Not-a-Number)*1 について。C/C++標準ライブラリはquiet NaN*2を返すnan関数を提供し、同関数では処理系定義(implementation-defined)のタグ文字列を受け取る。一般的には空文字列""を指定するが、ライブラ…

CUDA同期メモリ転送関数 != 同期動作

CUDAメモリ転送系関数の Async サフィックス有無*1と、実際の同期(synchronous)/非同期(asynchronous)動作は1:1対応しない。Asyncサフィックス無しメモリ転送関数でも、条件によっては非同期動作となる可能性がある。 API synchronization behavior The API…

Hidden Friends

C++

プログラミング言語C++におけるライブラリ設計で「ADL(Argument Dependent Lookup)経由でのみ呼び出し可能な非メンバ関数/演算子オーバーロード 定義」を実現するテクニック。2019-12-03追記:2019年11月会合にて (PDF)P1965R0 が採択され、C++標準規格上の…

定数式を要求するコンセプト

C++2a(C++20) Conceptを利用した「ある式が定数式であること」を要求する制約式の定義。型パラメータTに対して「T::size()がコンパイル時に評価されること」を要求するコンセプトHasConstantSizeの定義例。requires式中の typename type-name; 構文(type-req…

書式指定子の入れ子

プログラミング言語Pythonの str.format や f-string*1 において、書式指定子部のみ1段階の入れ子が許容される。下記コードではいずれも文字列 Hello!!!!! が得られる。 msg = 'Hello' '{:!<10}'.format(msg) f'{msg:!<10}' f, a, w = '!', '<', 10 '{:{}{}…