2021.1.6

C++ コードメモ(インクルードガード、文字列の結合、スタックオーバーフローなど)

仕事で10年以上ぶりくらいにC++のプロジェクトに関わることがあったので、その時に調査したことや、開発で気を付けておきたいことなどをメモとして残しておきます。

久しぶりでしたが、C++もバージョンアップで今時な書き方が意外とできるようになっていたので、ちょっと驚きました。

なお、C++の最新の情報に詳しいわけではないのであしからず。

目次

  • インクルードガード(pragma once)
  • 文字列の結合
  • スタックオーバーフロー
  • longの2038年問題
  • autoの利用

インクルードガード(pragma once)

インクルードガードはC++のヘッダファイルが重複して呼び出されるのを防ぐためのもので、古いものはifndefとdefineで実装されていましたが、pragma onceで置き換えが可能。

◆古い書き方


#ifndef INCLUDE_HOGE_H
#define INCLUDE_HOGE_H

void hoge(void);

#endif

◆最新の書き方


#pragma once
void hoge(void);

文字列の結合

C++で一番ハマったのは文字列の扱い。

C言語では文字列の最後は終端文字(\0)となり、文字列を結合する際には、この終端文字の分も含めて領域を確保する必要があります。

例えば、3文字(abc)と3文字(def)の文字列を結合する場合、7文字分の領域が必要です。


char str[7];
const char *s1 = "abc";
const char *s2 = "def";
strcpy_s(str, s1);
strcat_s(str, s2);
OutputDebugString(str);

char str[7]char str[6]のように書き換えるとエラーが出ます。(エラーが出ない場合でも結合された文字を確認すると文字化けしている)

なお、上記のコードはマルチバイト文字セットで確認しています。マルチバイト文字セットとUnicode文字セットは「プロジェクトのプロパティ > 全般 > 文字セット」から変更可能。

参考)_T("")マクロだのL""マクロだのLPCTSTRだのの世界一詳しい解説

スタックオーバーフロー

こちらもハマった問題で、携わったプロジェクトのスタックのサイズがかなり低く設定されていたため、ちょっとコードを追加しただけなのに、デバッグ中にスタックオーバーフローが発生するようになったことがありました。

スタックのサイズは「プロジェクトのプロパティ > リンカー > システム > スタックのサイズの設定」から変更可能です。

Visual Studioのデフォルトは1MB。

デバッグ実行中にスタックオーバーフローが発生した場合、まず、この設定を確認した方がいいかもしれません。

参考)/STACK (スタック割り当て) | Microsoft Docs

longの2038年問題

32ビットのアプリケーションで、日時の情報をlongで格納している場合は2038年問題に気を付けなければいけません。

これは32ビット環境でのlongが4バイトで、1970年からの秒数で日時を表している場合、2038年までしか数えられないことが原因です。

Visual Studio 2005以降はtime_t(__time64_t と同じ)に置き換えることで解決可能。

参考)時間管理 | Microsoft Docs

autoの利用

最近では変数を「var」で宣言するのが当たり前になった感のある型推論によるデータ型の省略ですが、C++ 11からは「auto」で同様な記述が可能となっているようです。


auto i = 0;

データ型の省略はコードがかなり見やすくなるので、積極的に使っていきたいですね。

その他】関連記事