大阪市中央区 システムソフトウェア開発会社

営業時間:平日09:15〜18:15
MENU

C++でC風ライブラリを作る(環境変数編)

著者:高木信尚
公開日:2019/05/19
最終更新日:2019/05/19
カテゴリー:技術情報

高木です。こんばんは。

2月に始めたこの連載も、気がつくともう3ヶ月半もやっているんですね。
連載というのはネタ切れ防止にはいいので、当面は余裕だと思います。

一方でいい加減この連載も飽きてしまいそうです。
楽しみにしてくれている方が果たしているのかどうかわかりませんが、私自身が飽きてしまうのが一番の懸案です。

今後は別の連載も開始するなどして、ブログの内容にバリエーションを持たせていくことも考えています。
若手の社員がどの程度頑張ってブログを書いてくれるかにもよるので、もう少し様子を見ることにしましょう。

さて、今回は環境変数を取得するgetenv関数の置き換えを考えてみたいと思います。
標準規格のgetenv関数は使いにくい関数のひとつで、関数が内部的に管理している記憶域へのポインタを返します。
なので、スレッドセーフではありませんし、あとからもう一度getenv関数を呼び出すと、先ほど取得したポインタが指す内容は保証されなくなります。

getenv関数が返したポインタが空ポインタではないことを確認したら、ただちにstd::string型の変数に文字列をコピーしてしまうという手はすぐに考えつきます。
しかし、この方法ではスレッドセーフになりません。
今回作成するgetenvの代替関数で排他制御を行う手もありますが、何の支障もなくstd::getenv関数を呼べてしまうのでダメです。

標準規格の範囲内で実装することを諦めるなら、グローバル変数environまたは_environを使って自力で環境変数を探索すれば何とかなりそうです。
しかし、putenv関数やsetenv関数を使う場合にはスレッドセーフではなくなってしまいます。
どうせ標準規格の範囲から外れるのであれば、Visual C++のgetnenv_s関数や一部処理系で使えるgetenv_r関数に依存する手もあるのですが、処理系の網羅範囲に問題があります。

なかなか完璧な方法はないので、今回は可能な限り安全な実装方法を採用することで済ませましょう。

今回実装したgetenv関数を呼び出している最中に、別のスレッドでputenv関数やsetenv関数のような環境変数を変更する処理を行った場合は知りませんが、それ以外ならどうにかなりそうです。

    上に戻る