本記事はシリーズ「C/C++組込み開発者のためのDoxygen実践ガイド」の第2回です。
- 第1回:環境構築 — インストールからHTML出力まで
- 第2回(本記事):コメント記法と実践的な記載例
- 第3回:GitHub Actions + GitHub PagesによるCI自動ドキュメント生成
はじめに
第1回でDoxygenの環境構築とHTML出力の確認まで済みました。本記事では、実際にチームで使えるコメントの書き方を解説します。
「どのスタイルで書くか」「何を書けば十分か」という迷いをなくすために、よく使うコマンドの一覧と、関数・クラス・構造体・マクロ・ファイルヘッダそれぞれの記載例をセットで紹介します。
1. コメントスタイルの選択
Doxygenが認識するコメントスタイルは主に2種類あります。
Javadocスタイル(推奨)
/**
* @brief 関数の概要をここに書く
*/
Qtスタイル
/*!
* \brief 関数の概要をここに書く
*/
どちらも機能は同じです。C/C++組込みの現場では Javadocスタイル(/**)+ @ コマンド が広く使われており、既存のコーディング規約とも馴染みやすいため、本記事ではこちらを採用します。
チーム内でスタイルを統一することが最重要です。混在すると可読性が下がります。どちらを選ぶかより、どちらかに決めることを優先してください。
2. よく使うコマンド一覧
| コマンド | 用途 |
|---|---|
@brief |
概要(1行)。ドキュメント一覧ページに表示される |
@details |
詳細説明。省略した場合、@brief 後の段落が自動的に詳細説明として扱われる |
@param[in] |
入力パラメータ |
@param[out] |
出力パラメータ(ポインタ経由で値を返す場合) |
@param[in,out] |
入出力パラメータ |
@return |
戻り値の説明 |
@retval |
戻り値の具体的な値と意味(複数列挙できる) |
@note |
補足情報 |
@warning |
警告(使用上の注意など) |
@attention |
特に注意を促したい事項 |
@pre |
事前条件 |
@post |
事後条件 |
@code / @endcode
|
コード例の挿入 |
@see |
関連する関数・クラスへの参照 |
@file |
ファイルのドキュメントコメント(ファイル先頭に記載) |
@defgroup / @ingroup
|
モジュール(グループ)の定義と所属 |
3. 記載例:関数
組込みらしい例として、UART送信関数を示します。
/**
* @brief UART経由でデータを送信する
*
* 指定されたバッファの内容をUARTポートへ送信します。
* 送信完了まで本関数はブロックします。
*
* @param[in] port 使用するUARTポート番号 (0〜3)
* @param[in] buf 送信データのポインタ
* @param[in] len 送信バイト数
* @param[out] sent 実際に送信できたバイト数の格納先(不要な場合はNULL可)
*
* @retval 0 正常終了
* @retval -1 ポート番号異常
* @retval -2 タイムアウト
*
* @pre UART_Init() が事前に呼び出されていること
* @warning 割り込みコンテキストから呼び出してはならない
*
* @see UART_Init(), UART_Receive()
*/
int UART_Send(uint8_t port, const uint8_t *buf, size_t len, size_t *sent);
ポイント:
-
@retvalは@returnより具体的で、エラーコードが複数ある組込み関数との相性が良いです -
@pre/@warningで使用上の制約を明示すると、レビューや引き継ぎのコストが下がります -
@param[out]のsentのように「NULLを渡せるか否か」も書いておくと親切です
4. 記載例:構造体
/**
* @brief センサーデータ構造体
*
* 各センサーから取得した計測値と取得タイムスタンプを保持します。
*/
typedef struct {
uint32_t timestamp_ms; /**< 取得時刻 [ms](システム起動からの経過時間) */
int16_t temperature; /**< 温度 [0.1℃単位] 例: 250 → 25.0℃ */
uint16_t pressure; /**< 気圧 [hPa] */
uint8_t valid; /**< データ有効フラグ (1: 有効, 0: 無効) */
} SensorData_t;
ポイント:
- メンバ変数は
/**< ... */の行末コメントで記述します(/**との向きの違いに注意) - 単位・スケール・有効値範囲を明記すると、受け取り側の実装ミスを防げます
5. 記載例:クラス(C++)
/**
* @brief PWMコントローラクラス
*
* ハードウェアPWMタイマーを抽象化し、デューティ比・周波数の設定インタフェースを提供します。
*
* @note 1インスタンスにつき1チャンネルを占有します。複数チャンネルを制御する場合は
* インスタンスを複数生成してください。
*/
class PwmController {
public:
/**
* @brief コンストラクタ
* @param[in] channel 使用するPWMチャンネル番号 (0〜7)
* @param[in] freq_hz 初期周波数 [Hz]
*/
PwmController(uint8_t channel, uint32_t freq_hz);
/**
* @brief デューティ比を設定する
* @param[in] duty_percent デューティ比 (0〜100 [%])
* @retval 0 正常
* @retval -1 範囲外
*/
int setDuty(uint8_t duty_percent);
/**
* @brief PWM出力を停止する
*/
void stop();
private:
uint8_t channel_; /**< PWMチャンネル番号 */
uint32_t freq_hz_; /**< 設定周波数 [Hz] */
};
6. 記載例:マクロ
/**
* @defgroup TIMEOUT_DEFS タイムアウト定数
* @brief 各モジュールのタイムアウト設定値
* @{
*/
/** @brief UART受信タイムアウト [ms] */
#define UART_RECV_TIMEOUT_MS 100U
/** @brief SPI転送タイムアウト [ms] */
#define SPI_TRANSFER_TIMEOUT_MS 50U
/** @brief 最大リトライ回数 */
#define MAX_RETRY_COUNT 3U
/** @} */ /* TIMEOUT_DEFS */
ポイント:
-
@defgroup/@{/@}でグループ化すると、関連するマクロがドキュメント上にまとめて表示されます - 末尾の
Uサフィックスは符号なし整数リテラル(unsigned)の明示です(MISRA-C準拠などで要求されるケースがあります)。意図をコメントで補足すると可読性が上がります
7. 記載例:ファイルヘッダ
すべての .c / .h ファイルの先頭に記載します。
/**
* @file uart_driver.c
* @brief UARTドライバ実装
*
* STM32F4シリーズ向けUARTドライバです。
* 送受信はFIFOバッファ経由で行い、割り込み駆動で動作します。
*
* @author Harada Yusuke
* @date 2025-04-01
* @version 1.2.0
*
* @copyright Copyright (c) 2025 Your Company. All rights reserved.
*/
@file を記載しないと、そのファイルのグローバル変数や関数がDoxygenの出力に含まれないことがあります。必ず記載してください。
8. チームへの展開:コーディング規約への組み込み方
Doxygenコメントをチームに定着させるためには、「書くかどうか個人の判断に任せる」ではうまくいきません。以下の観点でコーディング規約に明文化することを推奨します。
最低限ルール化すべき項目:
- スタイルの統一(Javadocスタイル固定)
-
@fileの必須記載 - 公開関数・公開クラスへの
@brief/@param/@returnの必須記載 - メンバ変数の行末コメント(
/**< */)の推奨
レビューチェックリストへの反映例:
□ @file が記載されているか
□ 公開関数に @brief / @param / @retval が揃っているか
□ 単位・有効値範囲がコメントに含まれているか
□ @warning / @pre で使用上の制約が明示されているか
Doxygenコメントのレビューを「ドキュメントレビュー」ではなく「コードレビューの一部」として扱うことで、自然に品質が上がっていきます。
まとめ
本記事では以下を解説しました。
- Javadocスタイルの採用とチーム統一の重要性
- よく使うコマンド一覧(
@param,@retval,@pre,@warningなど) - 関数・構造体・クラス・マクロ・ファイルヘッダの記載例
- コーディング規約・レビューチェックリストへの組み込み方
次回は、これらの設定をGitHub Actionsと連携させ、mainへのpushのたびに自動でドキュメントを生成・公開する仕組みを構築します。