yohhoyの日記

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

C++

std::byte型あれこれ

C++1z(C++17)で導入されるstd::byte型に関するメモ。コンパイル時型検査による安全性向上を目的として、「バイト(byte)」を表す標準データ型として導入される。C++標準ライブラリの拡張だけではなく、C++言語仕様にも特別扱いが追加される。 // 標準ヘッダ<cstddef> n</cstddef>…

signatureの定義

C++

プログラミング言語C++における関数シグネチャ(signature)の定義についてメモ。 2021-09-27追記:C++20以降の関数シグネチャ定義は signatureの定義 @ C++20 を参照のこと。まとめ: 関数:名前、引数型リスト、所属する名前空間(戻り値型は除外) 関数テン…

C標準ヘッダ in 未来のC++

プログラミング言語C++標準規格におけるC標準ヘッダ(<stdlib.h> や <stdio.h> など)の扱いについて。2021-10-27追記:C++2b(C++23)に向けた提案 P2340R1 が採択され、全てのC標準ヘッダについて廃止予定が取り止められた。例えば<iso646.h>ヘッダは空っぽ、<complex.h>ヘッダは#include <complex>と規定され</complex></complex.h></iso646.h></stdio.h></stdlib.h>…

recursive_(timed_)mutexの再帰ロック数上限

C++

C++11標準ライブラリのstd::recursive_mutex, std::recursive_timed_mutexクラスでは、同一スレッドからの再帰ロック獲得回数の上限は未規定(unspecified)となっている。一方で上限回数を超えるtry_lock操作は失敗し、lock操作は例外送出することは保証され…

shared_(timed_)mutexがサポートするReaderスレッド数

C++

C++14標準ライブラリのshared_timed_mutexクラス*1は、少なくとも10000スレッド以上のReaderスレッドからの共有ロック(shared lock)同時獲得をサポートする。また同時獲得可能な共有ロック数上限を超えた場合も、共有ロック獲得できるまでReaderスレッドがブ…

i = i++ + 1;の評価順規定

プログラミング言語C++における評価順規定の変遷についてメモ*1。本記事では代入+前置/後置インクリメント*2+加算演算子*3 *4を扱う。注意:本記事は言語仕様の隅をつつく話題であり、一般論として同一オブジェクトに対する複数回の副作用を伴う式文は避…

数字から数値への変換: ch - '0'

C C++

プログラミング言語C/C++における、1文字の数字から1桁の整数値へ変換するイディオム ch - '0' について。C/C++言語仕様では、数字の文字コード'0'〜'9'がその並び順で連続かつ隣接すると保証する。このため変換元文字chから数字0の文字コード'0'を減算する…

shared_ptr参照カウントとデータ競合

C++1z(C++17)標準ライブラリでは、スマートポインタstd::shared_ptr<T>のuniqueメンバ関数は非推奨(deprecated)とされる*1。上位互換となるuse_countメンバ関数は残存するが、スレッド間同期には関与しないという要件が明確化され、マルチスレッド実行ではその</t>…

<--(中略)-- 演算子

C++

プログラミング言語C++のヘンテコな演算子。💘(U+1F498) #include <iostream> int main() { int n = 100; while ( 0 <-------------------- n) { // !? std::cout << n << ' '; } } 実行結果: 90 80 70 60 50 40 30 20 10 タネ明かし 前掲C++ソースコードの振る舞いを括</iostream>…

range-based forと文字走査

C++11で導入された range-based for 構文を用いて、文字列を一文字づつ走査する方法。*1 文字列リテラル 文字列リテラルはconst char配列型(→id:yohhoy:20150213)であるため、range-based for 構文による要素走査が可能。ただし文字列リテラル末尾に自動追…

initializer_listとMove-only型

C++

C++11で導入されたリスト初期化(list initialization)構文で用いられるstd::initializer_list<E>では、要素型Eにコピー操作を要求するため*1、std::unique_ptrなどのコピー不可/ムーブのみ可能な(Move-only)型を扱えない。この制限により Move-only 型の標準コ</e>…

なぜmutexオブジェクトはムーブできないか?

C++

C++標準ライブラリが提供するstd::mutexほか同期プリミティブ型*1は、意図的にコピー/ムーブ操作を禁止している。本記事の内容はStack Overflowで見つけた質問と回答に基づく。 #include <mutex> class X { int data_ = 0; std::mutex mtx_; using Lock = std::loc</mutex>…

int a = { 42, };

C++

プログラミング言語C++でのスカラ変数の初期化/代入において、Uniform initializationと冗長な末尾カンマ(,)を組み合せた例。構文上は許容されるが、分かりにくい書き方は避けるべき。 int a = { 42, }; // OK: 値42で初期化 int b = { 42 }; // OK: (同上)…

-Wpessimizing-moveオプション と -Wredundant-moveオプション

LLVM/Clangでは、戻り値最適化(RVO; return value optimization)を阻害する/単に冗長なstd::move関数利用を警告するオプションが提供される。Clang 3.7で追加された警告オプション。両オプションとも -Wall オプション指定に含まれるため、個別に指定するケ…

return文と暗黙のムーブと型変換

プログラミング言語C++において、関数からの return 文と暗黙のムーブと型変換の関係についてメモ。*1下記コードfunc_implicit_move関数のように return 文にて型変換(unique_ptr→shared_ptr)を伴う場合、C++11/14言語仕様によって振る舞いが異なる。この…

生文字リテラル中の改行コード

C++

C++11で導入された生文字列リテラル(raw string literal)に含まれる改行は、ソースコードファイルの改行コードによらず'\n'(LF)として扱われる。 std::string s = R"(abc xyz)"; assert(s == "abc\nxyz"); C++11 2.14.5/p4より引用。 [Note: A source-file n…

多値返却×型推論 in C++ (2)

C++1z(C++17)で導入予定の Structured Bindings と クラステンプレートの型推論 を組み合わせて、多値返却関数からの戻り値を型推論された個別変数にて受け取る方法。こちらは多値返却関数fooの戻り値を型推論する前提。 // C++1z(C++17) #include <cassert> #include <string></string></cassert>…

多値返却×型推論 in C++ (1)

C++1z(C++17)で導入予定の Structured Bindings*1 とstd::tupleコンストラクタの改善(→id:yohhoy:20150416)を組み合わせて、多値返却関数からの戻り値を型推論された個別変数にて受け取る方法。 // C++1z(C++17) #include <cassert> #include <string> #include <tuple> #include <type_traits> </type_traits></tuple></string></cassert>…

std::result_ofメタ関数のテンプレートパラメータ

C++

C++11標準ライブラリで導入されたstd::result_of<Fn(ArgTypes...)>メタ関数*1のテンプレートパラメータ部に関するメモ。2017-10-06追記:C++1z(C++17)ではstd::result_of<Fn(ArgTypes...)>メタ関数は非推奨(deprecated)とされ、替わりにstd::invoke_result<Fn, ArgTypes...>メタ関数が追加される。経緯はP0604R0</fn,></fn(argtypes...)></fn(argtypes...)>…

可変引数リストと非PODクラス型の関係・改

gcc(g++)5以降では、C言語スタイルの可変引数リスト(...)に非PODクラス型(≒普通のC++クラス型)を渡すことができる。注意:この振る舞いはgcc 5以降という特定の処理系でのみ合法であり*1、またC++の型システムを無視するため、強い理由がない限りは利用し…

auto as ラムダ式の戻り値型

C++

C++14以降では、ラムダ式の戻り値型(trailing-return-type)としてautoキーワードを指定できる。*1 // C++11ではNG/C++14以降はOK auto f = [](int a, int b) -> auto { // int型に推論 return a + b; }; auto h = [](auto& v) -> decltype(auto) { return v…

ローカル変数アドレス返却とgccの挙動

警告:C/C++言語においてはローカル変数*1はその変数スコープ内(関数やブロック)でのみ有効であり、同変数へのポインタ値をスコープ外に持ち出すと未定義動作(undefined behavior)を引き起こす。本記事の内容は未定義動作に依存しているため、実行環境のOS…

ref-qualifierの使い道

C++

C++11で追加されたメンバ関数への参照修飾(ref-qualifier)の使い道についてメモ。 メンバ変数からのムーブ メンバ変数へのアクセサ関数を定義する場合、(1)非const参照を返す非constオーバーロード関数と、(2)const参照を返すconstオーバーロード関数を提供…

std::arrayの(ほぼ)constexprネイティブ対応

C++1z(C++17)標準ライブラリのシーケンスコンテナstd::array<T,N>では、ほぼ全てのメンバ関数*1がconstexpr指定される。あわせて、関連するイテレータ型やbegin/end関数群*2へもconstexpr指定が追加される。2019-09-11追記:C++2a(C++20)に向けて (PDF)P1023R0、P</t,n>…

文字列取得バッファとしてのstd::string リターンズ

C++1z(C++17)標準ライブラリの文字列型std::basic_string<charT>クラステンプレートでは、ポインタ型charT*を返す 非const版 dataメンバ関数が追加される。(ポインタ型const charT*を返すconst版dataメンバ関数はC++98から存在している。)まとめ: C++98/03標準ラ</chart>…

std::clamp

C++1z(C++17)標準ライブラリでは、指定区間内に値を制限するstd::clamp関数テンプレートが追加される。*1 #include <algorithm> int b = std::clamp(3, 1, 6); // 3 int a = std::clamp(0, 1, 6); // 1(下限値) int c = std::clamp(8, 1, 6); // 6(上限値) 同様の関数テ</algorithm>…

可変引数リストと文字列とヌルポインタの特別な関係

C C++

C言語の可変引数リストと文字列(文字型へのポインタ)とヌルポインタの関係についてメモ。下記コードではvoid*型をもつマクロNULLの値*1を、関数f実装ではchar*型として展開するが、両ポインタ型は互換型(compatible type)とみなされない*2。関数呼び出し側…

標準ライブラリrandomの分布生成器は処理系依存

C++

C++標準ライブラリ<random>で提供される分布生成器(distribution)は、具体的なアルゴリズムまで規定しないため処理系毎に異なる乱数列が得られる。乱数生成エンジン(engine)のアルゴリズム/パラメータが言語仕様で定義されるのとは対照的(→id:yohhoy:20130719)。 </random>…

size_tと値-1

C C++

C/C++言語における符号無し型と負数の扱いについてメモ。値-1をsize_tなどの符号なし整数型*1へ変換代入する場合、同型の最大値となることが保証される。この振る舞いは符号付き整数型の内部ビット表現に依存しない。*2 const size_t nmax = -1; // nmaxはsi…

C++ demangler on Web

オンラインでC++名前デマングル結果を確認できるWebサービス。gcc(g++), Microsoft Visual C++(MSVC)に対応。 https://demangler.com/ GCC and MSVC C++ Demangler https://d.fuqu.jp/c++filtjs/ c++filtjs 関連URL Is there an online name demangler for C…