C++

2023年のコンパイル時レイトレーシング

C++

これは qiita.com の12/16の記事です。やばいもう16日が終わってしまう! はじめに 太古の昔、あるC++プログラマ*1がtemplateの再帰と特殊化を使ってコンパイル時に計算ができることを「発見」*2*3したその日から、C++とコンパイル時計算は分かちがたく結び…

boost-ext/ut の使い方

C++

しばらくブログを書けていなかったのでちょっと準備運動をする。比較的長めのものをこれから書こうと思っているからだ。 github.com boost-ext/μtは、C++20用のテストライブラリだ。C++20らしくモジュールとしても使えるし、シングルヘッダオンリーライブラ…

Boost math constantsの変遷記録

C++

今日気づいたのだが、Boost.math.constants にある one_div_pi は Boost 1.71.0 以前には存在しない。 背景 Boost.math.constantsは、現時点ではC++で数学定数を取得するために最もよい方法だろう。これは、以下のようにして数学定数を取得できるライブラリ…

特殊化が存在するかどうかをチェックする

C++

機能の紹介 toml11では、ユーザー定義型との間にいくつかの変換方式を提供している。 1つめはtoml::valueを受け取るコンストラクタを使用するもの。続いてfrom_toml(const toml::value&)というメンバ関数を定義するもの。最後にtoml::from<T>という構造体を定義</t>…

GCCの-Wshadowとその推移について、あとお前を消す方法

C++

-Wshadowは-Wallでオンにならない警告オプションで、shadowingを警告してくれる。 そもそも、実はC++にもshadowingというのはあり、ブロックを分けさえすれば同じ名前の変数を定義しても特に問題はない。ブロックが同じだとエラーになるのであまり便利ではな…

ビルドもできるヘッダオンリーライブラリ

C++

長いことまともな記事を書いていないのでリハビリをします。 ヘッダオンリーライブラリとして使えるものの、必要な場合はコンパイルできる、というライブラリはチラホラ見かける。例えば spdlog はその一つで、 "header only/compiled library" を名乗ってい…

Static Initialization Order Fiasco

C++

これはC++アドベントカレンダーが埋まっていなかったので急遽書こうと思い立って急いで寝る前にバーっと書いてたら気づいたときには2時を回っていた記事です。何かあったら教えるか見逃してください。 そもそも何の話? Static Initialization Order Fiasco…

__VA_ARGS__の引数をループするやつはなぜ動くのか

C++ C

今更マクロの話です。求められてるのはそういうのではなくモダンな解決方法の話だということは知っているけれど、例えばreflection TSとかは紹介するには重すぎるので……。まあとりあえず今回は伝統的なテクニックの話をします。他所でも解説されている可能性…

gcc 4.8.xでの標準ライブラリのバグについて

結構昔に書いていたっぽい下書きがあったので手直しして出しておこう。まあイマドキgcc-4.8.5を使う羽目になっている人はあまりいないだろうが、少なくともIssueが立つ程度には存在するようなので。 広く知られていることっぽいが、GCC 4.8系統の標準ライブ…

テンプレート非型メタプログラミングでコンパイル時LISPを書く

C++

人類はちょっと窮屈な言語があったらすぐLISPとかBrainfxxkを作る 前回の記事でC++20でテンプレート非型メタプログラミングが簡単にできるようになって嬉しいねという話をした。まあ実際には型に情報を埋め込んでいるのでこの呼び名はミスリードだが。 やろ…

テンプレート非型メタプログラミング

C++

C++での黒魔術といえばテンプレート型メタプログラミングだ。これは、テンプレートがパターンマッチと再帰を使えることを利用して、型レベルで計算を行う技術を指す。 template<int X> struct factorial { // 再帰的に展開できる static const int value = factorial<X-1></x-1></int>…

variadic templateを前に置きたい!

C++

variadic templateを関数の引数にすると最後までマッチしてしまうので関数の先頭に任意個の引数を取るような関数を書けない。困りますよね。 可変個の引数を先に渡して、最後に追加で何かを渡したい、そんなこともあると思います。 template<typename ... Ts, typename F> void f(Ts&& ...</typename>…

C++ Conceptとエラーメッセージ

C++

C++20 Conceptに少し慣れようと思い、練習がてら雑JSONを出力できるライブラリを書いてみようと思った。 C++20となると色々考えるべきことが増える(std::u8stringをどうするか? とか)が、今回はそのへんは主題ではないのでできるだけ今までのC++の範囲内…

trailing comma問題

C++

別名ケツカンマ問題。 最後の要素の後にはカンマを入れてはいけない、という場合にどう対処するか。 要素のインデックスやイテレータを使ってループしているなら、普通にそれを見ればいい。 std::cout << "["; for(std::size_t i=0; i

static variableの初期化順序

C++

template structの中にstaticなstd::mapを作ってmain()よりも前にアクセスしたらその時点ではまだコンストラクタが呼ばれておらず、中身がゼロ埋めされていてセグフォになった。 静的変数の初期化順序は基本的に書いた順、翻訳単位が違ったら実装定義、実装…

std::variantと不動点演算子

C++

実は、std::vectorはC++17から不完全型をサポートしたので、std::variantと組み合わせると以下のようなコードが書ける。 struct config_t { std::variant<bool, int, double, std::string, std::vector<config_t>> data; }; これを上手く使えばJSONなどの木構造をかなり簡単に(ポインタを陽に触らずに)扱える。std</bool,>…

x64で配列の添字にintを使うと遅い

こういうツイートを見た。気になったので試してみたら本当にそうらしい。 x64でEAXに値を入れるとRAXの上位は(符号拡張ではなく)0になる。なのでC/C++で配列の添え字に32bit整数を使うと符号拡張命令が追加されて遅くなる。LP64環境で配列の添え字にintを使…

thrustのバグを見つけて直した話

thrustがasync対応していたのを先月見つけた。 in-neuro.hatenablog.com ドキュメントがまるで書かれていないところをコードを読み進めて試していたのだが、そこで不可解な動作を発見した。 以下のようなコードを書いたとする。thrustの関数を非同期に読んで…

OpenMPの挙動を見る

少し前、ちょっと面白い挙動に出くわしたので、順を追って説明しておこうと思った。知ってる人には当たり前のことが書かれているので下の方まで飛ばしてくれても構わない。 OpenMPはプラグマを書くだけでメモリ共有並列化ができるというやつで、手をつけやす…

CMake 3.16でprecompiled headerがサポートされていた

CMakeの最新バージョン、3.16でtarget_precompile_headerがサポートされていた。ドキュメントは以下の通り。 cmake.org precompiled headerは、大規模なプロジェクトなどで変更がないのに様々な.cppファイルから何回もインクルードされるヘッダーファイルを…

-ffinite-math-onlyでも動くNaN/infチェック

以前こういう記事を書いた。 in-neuro.hatenablog.com まあNaNじゃないことを仮定しての高速化なんだからstd::isnan(x)を常にfalseだと思ってdead code eliminationするのは当たり前じゃんという気はするが、備忘録的に。 とはいえ、コンパイルオプションに-…

thrustにasyncサポートが入っていた

thrustというライブラリがある。 thrust.github.io 直接使ったことがなくても、CUDAをインストールしたら付いてくるので知らずにインストールしている人は多いと思う。 これはCUDAをC++で使う上で最高レベルに便利なライブラリで、もはやこれ無しでCUDAプロ…

toml11をマイナーアップデートした

しばらく前だが、アップデートした。最新バージョンはv3.1.0だ。 Added TOML11_USE_UNRELEASED_TOML_FEATURES TOML言語仕様はまだちょいちょいバージョンアップされている。なので「TOMLとしてリリースされていないがtoml-lang/toml:masterにmergeされた、お…

インデントのスタイルについて

C++

そういえば、自分のインデントスタイルについて人に話すことってないなと思ったので。 インデントやコードのスタイルは初心者には軽視されがちだ。なぜならそれは「本質ではない」からだ。どんなコーディングスタイルでも動くものは動く。コンパイラにとって…

入力に応じてテンプレート引数を変える

C++

C++は静的に型付けを行うので、基本的に実行時に型を切り替えることはできない。なので、入力に応じて異なる型を返すことはできない。だが継承を使っているなら、常に基底クラスへのポインタを返しつつ、入力に応じて派生クラスのテンプレート引数を変更する…

-OfastはNaNチェックを無効化する

C C++

gccには-Ofastというオプションが存在する。これは、標準規格への適合性を犠牲にしてでも高速なバイナリを吐くモードだ。色々なことが犠牲になるが、NaNチェックも犠牲になる。 以下のコードを見て欲しい。 wandbox.org #include <iostream> #include <cassert> #include <cmath> int m</cmath></cassert></iostream>…

templateクラスを継承するtemplateクラスのデストラクタをoverrideし、かつdefault指定してextern templateでビルドするとintel compiler (v18)だけlink errorになる

C++

タイトルが長い。 でもこれ以上何かを削ると不正確なタイトルになる。もしかするともう少し条件を広げても同じエラーが出るかも知れないが。 extern templateというのがあり、以下の記事に詳しい。 qiita.com かい摘んで説明しておこう。ヘッダファイルでext…

メモ:cerealと派生クラス2

C++

cerealで継承を使ったサンプルを少し前に掲載したが、これらのクラスがテンプレートだったらどうなるか。特に、継承関係を登録するマクロ。 この部分だ。 CEREAL_REGISTER_TYPE(sample::Derived) CEREAL_REGISTER_POLYMORPHIC_RELATION(sample::Base, sample…

メモ:cerealと派生クラス

メモです。cerealは説明不要のシリアライズ用ライブラリ。 派生クラスをstd::unique_ptr<Base>として持っている時の最小サンプル。 cereal::base_class<Base>(this)をシリアライズするのを忘れない CEREAL_REGISTER_TYPE(sample::Derived)を名前空間の外に書く。セミコロ</base></base>…

parallel linear BVH (LBVH) をCUDA+thrustで書いた

久々に少し非自明なことをCUDA+thrustでやった。大体動くようになるまでまる一日(半日+半日なので別のmetricsでは2日)かかった。 github.com BVHとはなんぞやという話は、以下の記事にとてもよくまとまっている。というか、多分この記事の著者は私のような…