std:: の標準ライブラリの代わりに y3c:: 以下のクラスを使うことで、例外がcatchされなかった場合や未定義動作の代わりにわかりやすいエラーメッセージとスタックトレースを表示します。 C++初心者におすすめです。
Linux, MacOS, Windows (MSVC, MinGW) で動作確認しています。 スタックトレースの取得と表示に関しては cpptrace ライブラリを使用しています。
#include <y3c/vector> // <= instead of <vector>
#include <iostream>
int main() {
y3c::vector<int> a = {1, 2, 3, 4, 5}; // <= instead of std::vector<int>
y3c::vector<int>::iterator it = a.begin();
a.resize(100); // reallocation occurs here and
std::cout << *it << std::endl; // <= this would be undefined behavior, but...
}
↓
y3c-stl terminated: undefined behavior detected (ub_access_deleted)
at y3c::vector<int>::iterator::operator*(): attempted to access the deleted value.
Stack trace (most recent call first):
#0 0x000056364363f72e in main at /home/runner/work/y3c-stl/y3c-stl/build/../examples/vector-iter-reallocate.cc:8:18
6: y3c::vector<int>::iterator it = a.begin();
7: a.resize(100);
8: std::cout << *it << std::endl;
9: }
こちらから他のサンプルコードと実行結果の例を見ることができます。
brew tap na-trium-144/y3c
brew install y3c-stl
でインストールできます。
Meson (>=1.1) をインストールしてください。
- Ubuntu:
pip install meson
またはsudo apt install meson
- MacOS:
brew install meson
- Windows MSVC: 公式サイト からダウンロードしてください。
- MSYS2:
pacboy -S meson
以下のコマンドでy3c-stlと依存ライブラリをビルド、インストールできます。
git clone https://github.com/na-trium-144/y3c-stl
cd y3c-stl
meson setup build
meson install -Cbuild --skip-subprojects
Windowsの場合は meson setup 時の引数で -Dprefix=C:/Users/hoge/y3c
などとインストール先を指定するとよいです。
Linux,Macの場合は特にこだわりがなければ何も指定せずデフォルトのまま (/usr/local
など) がおすすめです。
また、Windows MSVC の場合は release ビルド(デフォルト)と debug ビルド(meson setup 時に -Dbuildtype=debug
を指定)の両方をインストールする必要があります。
- y3c-stlは y3c という名前の共有ライブラリとなっているのでそれをリンクするだけでokです。
- ただしWindowsのMSVCでdebugビルドの場合は y3cd という名前になります。
- また、Windowsの場合はy3cのdllファイル(インストール場所のbinディレクトリにあります)を実行ファイルと同じディレクトリにコピーするか、PATHを通す必要があります。
- Linux,Macでインストール先がデフォルトの場合は
-ly3c
と-g
を渡せばよいです。- インストール先を変更している場合は
-I/path/to/y3c/include -L/path/to/y3c/lib -ly3c
などとパスも指定する必要があります。 -g
はなくてもビルドできますが、スタックトレースが表示されなくなります。
- インストール先を変更している場合は
- コンパイラによってはさらに
-std=c++11
またはそれ以上がないとコンパイルエラーになる場合があります。 - Windows MSVCの場合は
/IC:\path\to\y3c\include
と/libpath:C:\path\to\y3c\lib
でパスを指定し、y3c.lib
(releaseビルドの場合) またはy3cd.lib
(debugビルドの場合) を渡してください。
- コンパイラの引数に
$(pkg-config --cflags --libs y3c)
と-g
を渡せば良いです。- インストール先を変更している場合は
PKG_CONFIG_PATH
環境変数に/path/to/y3c/lib/pkgconfig
などを追加する必要があります。
- インストール先を変更している場合は
- コンパイラによってはさらに
-std=c++11
またはそれ以上がないとコンパイルエラーになる場合があります。
find_package(y3c REQUIRED)
target_link_libraries(your_target y3c::y3c)
y3c_dep = dependency('y3c')
executable('your_target', ..., dependencies: y3c_dep)
- std:: 以下の各種クラスの代わりに y3c:: 以下のクラスで置き換えることで、よくある例外や未定義動作についていろいろな追加のチェックが実行時に行われます。
- さらに
int
などのクラスでない変数についてはy3c::wrap<int>
、配列int[5]
→y3c::wrap<int[5]>
、参照int&
→y3c::wrap<int&>
、 生ポインタint*
→y3c::wrap<int*>
で置き換えることで、nullptrや範囲外へのアクセス、また寿命が切れた変数へのアクセスかどうかをチェックすることができます。 - いずれも
y3c::unwrap()
(またはunwrap()
) 関数を使うことで対応する std:: 以下のクラス、wrap元の型(の参照)に復元できます。 (unwrap後はチェックが行われませんが)
- さらに
- 例外を投げるパターンの場合は (例えば
std::array::at()
→std::out_of_range
)、 それがcatchされなかった場合にわかりやすいエラーメッセージとスタックトレースを表示します。- 通常の例外と同じようにcatchすることも可能です。(その場合は何も表示されません)
- catchする場合はstdクラスの場合と同様に std:: の例外クラスでcatchできます。
継承関係もそのままです。
(例えば
std::out_of_range
はstd::logic_error
,std::exception
としてもcatchできます。)
- 未定義動作を起こすパターンの場合、エラーメッセージとスタックトレースを表示した後 abort() します。
- スタックトレースの表示処理は
std::set_terminate()
に登録したハンドラーの中で行っているため、 y3c:: のラッパークラス以外が投げた標準のexceptionや、直接std::terminate()
を呼び出した場合もスタックトレースが表示できる場合があります。
- nullptrアクセスのチェック
- 範囲外アクセスのチェック
- 寿命が切れた値へのアクセスのチェック
ただしいずれもチェックされる条件として生ポインタや参照の代わりに y3c::ptr
, y3c::wrap_ref
などを使用することに加えて、
アクセスする対象も y3c:: のクラスまたは y3c::wrap
でラップされている必要があります
リンクはDoxygenによるドキュメントへのリンクです。
#include <y3c/wrap>
(y3c独自のユーティリティ関数、STLのクラスに属さないものなど)- y3c::link()
- y3c::unwrap(y3c::wrap<T>)
- y3c::wrap<T> ←
T
- y3c::wrap<T&> ←
T&
- y3c::wrap_ref<T> =
y3c::wrap<T&>
- y3c::const_wrap_ref<T> =
y3c::wrap<const T&>
- y3c::wrap_ref<T> =
- y3c::wrap<T*> ←
T*
- y3c::ptr<T> =
y3c::wrap<T*>
- y3c::const_ptr<T> =
y3c::wrap<const T*>
- y3c::ptr_const<T> =
const y3c::wrap<T*>
- y3c::const_ptr_const<T> =
const y3c::wrap<const T*>
- y3c::ptr<T> =
#include <y3c/array>
- y3c::array<T, N> ←
std::array<T, N>
- y3c::array<T, N> ←
#include <y3c/vector>
- y3c::vector<T> ←
std::vector<T>
- y3c::vector<T> ←
#include <y3c/memory>
- y3c::shared_ptr<T> ←
std::shared_ptr<T>
- y3c::make_shared<T>() ←
std::make_shared<T>()
- y3c::make_shared<T>() ←
- y3c::shared_ptr<T> ←
y3c-stlはMITライセンスの下で公開されています。
依存ライブラリとして cpptrace (MITライセンス), libdwarf (LGPL), rang (Unlicense) を使用しています。