Microsoft GSL(Guidelines Support Library) ライブラリの導入

提供:yonewiki
2024年2月27日 (火) 15:47時点におけるYo-net (トーク | 投稿記録)による版 (→‎使い方)
(差分) ← 古い版 | 最新版 (差分) | 新しい版 → (差分)

言語と開発環境に戻る。

概要

 GSLというのはGuidelines Support Libraryのことをここでは言っていますが、まったく同じ略称でGNU Scientific Libraryというものもありますので、ご注意を。


 Microsoftが提供しているものなので、Microsoft GSLと書けば、Guidelines Support Libraryに絞られます。C98規格にも対応するGSL Liteというものもあるそうです。Liteとつかないものは、C++14以上を対象にしているように見受けられます。


 公式サイトはhttps://github.com/microsoft/GSLのGithubにあるようです。


 C++コードの品質、可読性、およびセキュリティを向上させるために提供されるオープンソースのライブラリです。GSLは、C++ Core Guidelines(C++の設計およびプログラミングに関する一連のガイドライン)に基づいています。これらのガイドラインは、C++プログラムの安全性と効率性を向上させるためのベストプラクティスを提供しています。


  • gsl::span:
 メモリ領域を指す軽量かつ安全なスライスを表現するためのクラス。範囲の概念を提供し、メモリのアクセスや操作を安全に行うことができます。
  • gsl::index:
 インデックスの範囲を表現するためのクラス。インデックスの有効性を確認し、オーバーフローやアンダーフローを防ぐために使用されます。
  • gsl::not_null:
 ポインタがnullでないことを表現するためのクラス。nullポインタの不正な使用を防ぎ、プログラムの安全性を向上させます。
  • gsl::narrow_cast:
 整数型の変換を行うための関数。情報の損失がないかを確認し、損失が発生する場合は警告を発生させます。

 

導入方法

 https://github.com/microsoft/GSLよりコードボタンのZIPダウンロードを選択して一式を展開し、任意のフォルダかプロジェクトに参加させるのであれば、プロジェクトを作ったフォルダの中に配置します。


 VisualStudioのプロジェクトのプロパティ([プロジェクト]-[(プロジェクト名)のプロパティ])で、VC++ディレクトリの項目に ;(配置した任意のフォルダ絶対パスorプロジェクトファイル.vcxprojからの相対パス) のように設定して、gslフォルダがある場所を示します。gslフォルダの中にはalgorithm, assert, byte, gsl, narrow, pointers, span, span_ext, string_span, util, zstringのようなファイルがある状態です。


 利用する場合はインクルード文を以下のように記述するだけですべての関数が使える状態になります。


#include <gsl/gsl>

 

使い方

narrow_cast

 例えば、gsl::narrow_castはその中の一部で、型の変換を行う際に安全なキャストを行うための関数です。以下のようにして使います。std::sizeの型変換を安全に行うために以下のような記述をします。


template <typename To, typename From>
constexpr To Function_Name(From from) {
    return gsl::narrow_cast<To>(std::size(from));
}

具体的には、以下のように使います。

template<class Size, class Source>
constexpr auto size_as(Source const& source) {
	return gsl::narrow_cast<Size>(std::size(source));
}


 このようにして定義されたsize_as関数は以下のようにして使うことができます。


#include <Windows.h>
#include <filesystem>//C++17以上

static std::filesystem::path const directory = [] {
  auto const length = GetSystemDirectoryW(data(directory), size_as<UINT>(directory));
  return directory;
}();


 このような型変換のチェックを強固にする利点はハードコーディングされる部分の数値的な変動が、型変換の範囲外にならないかを検出できる点にありますので、ユーザがプログラムを使うときにはじめてわかる値の変換などにはプログラマ自身が変換による不都合が出ないようにする必要があります。型変換のチェックを強固にしておくことで、将来的にコンパイルする時点で変動する値の変換エラーを検出することができるというのが大事なところです。


 こういった面倒な確認をするのに必要な処理のようなものを集めたライブラリです。その技術範囲はなかなか広大です。ここでは思いついた範囲でこのライブラリの使い方を記述していく予定ですが、どこまで言及できるかは不明です。第一弾はnarrow_castの紹介だったってだけです。次はないかもしれません。

 

finally

 finallyは、スコープから抜ける時に確実に実行される部分として定義できます。例えば、


void SomeFunction() {
    SomeContext sc;
    int CancelCheckWork = 0;

    // 何らかの処理があって、
    // ...

    auto cleanup = gsl::finally([&sc]() noexcept {CancelFunction((HANDLE)sc.handle);});


    // 途中で例外が発生したとしても、
    //cleanupがスコープを抜ける際に登録されたクリーンアップ処理が確実に実行される
}


 上記のように定義しれていれば、CancelFuctionの実行を持つラムダ式はSomeFunction内で例外が起こったとしても必ず初期化や後かたずけのような処理が行われます。この結果、cleanup関数には何らかの返り値を取得することが出来ます。この例では実行できたとて、外部への影響がないため、大きな変化はありませんが、SomeContextのような値が、関数のポインタ型引数になっていたりすると、sc値は何らかの値を保有することが期待できます。あるいはcleanupを返すような関数にもできます。

 

言語と開発環境に戻る。