Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

[インデックス 15244] ファイルの概要

このコミットは、Go言語のsyscallパッケージにおけるドキュメンテーションコメントの扱いを修正するものです。具体的には、//sysで始まる行がgodocによってドキュメンテーションコメントとして解釈されないように変更し、コードの可読性を保ちつつ、godocの出力をより一貫性のあるものにすることを目的としています。

変更されたファイルは以下の通りです。

  • src/pkg/syscall/syscall_bsd.go: BSD系のシステムコール定義に関連するファイル。
  • src/pkg/syscall/syscall_linux.go: Linux系のシステムコール定義に関連するファイル。

コミット

  • コミットハッシュ: 248d1446b53900b90d1279631a035508942d332c
  • Author: Brad Fitzpatrick bradfitz@golang.org
  • Date: Thu Feb 14 11:23:58 2013 -0800

GitHub上でのコミットページへのリンク

https://github.com/golang/go/commit/248d1446b53900b90d1279631a035508942d332c

元コミット内容

syscall: don't make //sys lines be doc comments

Cleans up godoc and makes it consistent. (some had it, some
didn't)

This still keeps the information there, though, for people
looking at the source directly.

R=golang-dev, minux.ma, rsc
CC=golang-dev
https://golang.org/cl/7324056

変更の背景

この変更の背景には、Go言語のドキュメンテーションツールであるgodocの挙動と、syscallパッケージ内の特殊なコメント形式//sysの相互作用がありました。

syscallパッケージでは、Goの関数がどのシステムコールに対応するかを示すために、//sysというプレフィックスを持つコメント行が使用されていました。例えば、//sys open(path string, mode int, perm uint32) (fd int, err error)のような形式です。

しかし、godocは通常、関数や変数などの宣言の直前にあるコメントをその要素のドキュメンテーションコメントとして解釈します。このため、//sysで始まる行が関数の直前に配置されている場合、godocはこれを通常のドキュメンテーションコメントとして扱ってしまい、生成されるドキュメントに不必要な情報が含まれたり、ドキュメントのフォーマットが一貫しなくなったりする問題が発生していました。

コミットメッセージにある「(some had it, some didn't)」という記述は、この//sysコメントがgodocによってドキュメンテーションコメントとして扱われるかどうかが、コードの記述方法によって異なり、一貫性がなかったことを示唆しています。

このコミットは、godocの出力を整理し、一貫性を持たせることを目的としています。同時に、//sys行自体はソースコードを読む開発者にとっては有用な情報であるため、その情報をソースコードから削除することなく、godocの解釈から除外する解決策が求められました。

前提知識の解説

Go言語のgodoc

godocは、Go言語のソースコードからドキュメンテーションを生成するためのツールです。Go言語では、関数、変数、型、パッケージなどの宣言の直前に記述されたコメントが、その要素のドキュメンテーションとして扱われます。godocはこれらのコメントを解析し、HTML形式などで整形されたドキュメントを生成します。これにより、開発者はコードとドキュメントを密接に連携させ、常に最新のドキュメントを維持することができます。

Go言語のsyscallパッケージ

syscallパッケージは、Goプログラムからオペレーティングシステムのシステムコールを直接呼び出すための機能を提供します。システムコールは、ファイルI/O、プロセス管理、ネットワーク通信など、OSカーネルが提供する低レベルなサービスを利用するためのインターフェースです。syscallパッケージは、OSに依存する低レベルな処理をGoから行う際に使用されます。

Go言語におけるドキュメンテーションコメントの規則

Go言語では、ドキュメンテーションコメントは特定の規則に従って記述されます。

  • 宣言の直前: ドキュメンテーションコメントは、それが説明する関数、変数、型、またはパッケージの宣言の直前に記述されます。
  • 空行: ドキュメンテーションコメントと宣言の間に空行があると、godocはそのコメントをドキュメンテーションコメントとして認識しません。これは、コメントがその宣言に直接関連していることを示すための重要な規則です。
  • パッケージコメント: パッケージのドキュメンテーションコメントは、通常、パッケージ宣言の直前に記述され、パッケージの目的や概要を説明します。

このコミットの変更は、特に「空行」の規則を利用して、//sys行がドキュメンテーションコメントとして解釈されないようにしています。

技術的詳細

このコミットの技術的な核心は、Goのgodocツールがドキュメンテーションコメントをどのように解釈するかという点にあります。godocは、コード要素(関数、変数など)の直前にあるコメントブロックをその要素のドキュメンテーションとして扱います。しかし、コメントブロックとコード要素の間に空行が挿入されると、godocはそのコメントブロックをドキュメンテーションコメントとは見なしません。

このコミットでは、syscallパッケージ内のシステムコールを定義するGo関数の直前に記述されていた//sysで始まる行と、実際のGo関数の間に意図的に空行を挿入しています。

変更前:

//sys open(path string, mode int, perm uint32) (fd int, err error)
func Open(path string, mode int, perm uint32) (fd int, err error) {
    // ...
}

変更後:

//sys open(path string, mode int, perm uint32) (fd int, err error)

func Open(path string, mode int, perm uint32) (fd int, err error) {
    // ...
}

このわずかな変更(//sys行の後に空行を追加)により、godoc//sys行をOpen関数のドキュメンテーションコメントとして認識しなくなります。その結果、godocによって生成されるドキュメントには//sys行が含まれなくなり、ドキュメントの出力がよりクリーンで一貫性のあるものになります。

コミットメッセージにある「This still keeps the information there, though, for people looking at the source directly.」という記述は、この変更が//sys行自体を削除するものではなく、ソースコードを読む開発者にとっては引き続きシステムコールに関する情報が利用可能であることを強調しています。これは、godocの出力とソースコードの可読性の両方を考慮した、バランスの取れた解決策と言えます。

コアとなるコードの変更箇所

このコミットでは、src/pkg/syscall/syscall_bsd.gosrc/pkg/syscall/syscall_linux.goの2つのファイルが変更されています。変更内容は非常にシンプルで、//sysまたは//sysnbで始まる行の直後に空行を追加することです。

src/pkg/syscall/syscall_bsd.go の変更

--- a/src/pkg/syscall/syscall_bsd.go
+++ b/src/pkg/syscall/syscall_bsd.go
@@ -20,6 +20,7 @@ import (
  /*
   * Pseudo-system calls
   */
+
 // The const provides a compile-time constant so clients
 // can adjust to whether there is a working Getwd and avoid
 // even linking this function into the binary.  See ../os/getwd.go.

この変更は、Pseudo-system callsセクションの直後にあるコメントブロックと、その後のconst ImplementsGetwd = trueの間に空行を追加しています。これにより、godocがこのコメントブロックをImplementsGetwd定数のドキュメンテーションコメントとして誤って解釈するのを防ぎます。

src/pkg/syscall/syscall_linux.go の変更

--- a/src/pkg/syscall/syscall_linux.go
+++ b/src/pkg/syscall/syscall_linux.go
@@ -18,16 +18,19 @@ import "unsafe"
  */
 
 //sys	open(path string, mode int, perm uint32) (fd int, err error)
+
 func Open(path string, mode int, perm uint32) (fd int, err error) {
 	return open(path, mode|O_LARGEFILE, perm)
 }
 
 //sys	openat(dirfd int, path string, flags int, mode uint32) (fd int, err error)
+
 func Openat(dirfd int, path string, flags int, mode uint32) (fd int, err error) {
 	return openat(dirfd, path, flags|O_LARGEFILE, mode)
 }
 
 //sysnb	pipe(p *[2]_C_int) (err error)
+
 func Pipe(p []int) (err error) {
 	if len(p) != 2 {
 		return EINVAL
@@ -40,6 +43,7 @@ func Pipe(p []int) (err error) {
 }
 
 //sysnb pipe2(p *[2]_C_int, flags int) (err error)
+
 func Pipe2(p []int, flags int) (err error) {
 	if len(p) != 2 {
 		return EINVAL
@@ -52,6 +56,7 @@ func Pipe2(p []int, flags int) (err error) {
 }
 
 //sys	utimes(path string, times *[2]Timeval) (err error)
+
 func Utimes(path string, tv []Timeval) (err error) {
 	if len(tv) != 2 {
 		return EINVAL
@@ -60,6 +65,7 @@ func Utimes(path string, tv []Timeval) (err error) {
 }
 
 //sys	utimensat(dirfd int, path string, times *[2]Timespec) (err error)
+
 func UtimesNano(path string, ts []Timespec) (err error) {
 	if len(ts) != 2 {
 		return EINVAL
@@ -79,6 +85,7 @@ func UtimesNano(path string, ts []Timespec) (err error) {
 }
 
 //sys	futimesat(dirfd int, path *byte, times *[2]Timeval) (err error)
+
 func Futimesat(dirfd int, path string, tv []Timeval) (err error) {
 	if len(tv) != 2 {
 		return EINVAL
@@ -99,6 +106,7 @@ func Futimes(fd int, tv []Timeval) (err error) {
 const ImplementsGetwd = true
 
 //sys	Getcwd(buf []byte) (n int, err error)
+
 func Getwd() (wd string, err error) {
 	var buf [PathMax]byte
 	n, err := Getcwd(buf[0:])
@@ -208,6 +216,7 @@ func (w WaitStatus) TrapCause() int {
 }
 
 //sys	wait4(pid int, wstatus *_C_int, options int, rusage *Rusage) (wpid int, err error)
+
 func Wait4(pid int, wstatus *WaitStatus, options int, rusage *Rusage) (wpid int, err error) {
 	var status _C_int
 	wpid, err = wait4(pid, &status, options, rusage)
@@ -809,6 +818,7 @@ func PtraceAttach(pid int) (err error) { return ptrace(PTRACE_ATTACH, pid, 0, 0)\n func PtraceDetach(pid int) (err error) { return ptrace(PTRACE_DETACH, pid, 0, 0) }\n \n //sys	reboot(magic1 uint, magic2 uint, cmd int, arg string) (err error)\n+\n func Reboot(cmd int) (err error) {\n 	return reboot(LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2, cmd, \"\")\n }\n@@ -848,6 +858,7 @@ func ParseDirent(buf []byte, max int, names []string) (consumed int, count int,\n }\n \n //sys	mount(source string, target string, fstype string, flags uintptr, data *byte) (err error)\n+\n func Mount(source string, target string, fstype string, flags uintptr, data string) (err error) {\n 	// Certain file systems get rather angry and EINVAL if you give\n 	// them an empty string of data, rather than NULL.\n```
このファイルでは、`open`, `openat`, `pipe`, `pipe2`, `utimes`, `utimensat`, `futimesat`, `Getcwd`, `wait4`, `reboot`, `mount`といったシステムコールに対応するGo関数の直前にある`//sys`または`//sysnb`行の後に、それぞれ空行が追加されています。

## コアとなるコードの解説

このコミットのコアとなる変更は、Go言語のドキュメンテーションツール`godoc`の挙動を制御するために、コメントとコードの間に空行を挿入するというGoの慣習を利用している点です。

Go言語では、`godoc`がドキュメンテーションコメントとして認識するのは、関数、変数、型などの宣言の直前に、間に空行を挟まずに記述されたコメントブロックのみです。もしコメントブロックと宣言の間に空行が存在すると、`godoc`はそのコメントをドキュメンテーションコメントとは見なしません。

`syscall`パッケージでは、Goの関数がどのシステムコールに対応するかを示すために、`//sys`や`//sysnb`といった特殊なコメント行が使用されていました。これらの行は、Goの関数定義の直前に記述されていたため、`godoc`はこれらを誤ってドキュメンテーションコメントとして解釈し、生成されるドキュメントに含めてしまっていました。これは、`godoc`の出力の一貫性を損ない、場合によっては不要な情報を提供することになっていました。

このコミットでは、`//sys`や`//sysnb`行の直後に空行を挿入することで、これらの行が`godoc`によってドキュメンテーションコメントとして扱われないようにしています。これにより、`godoc`はこれらの行を単なるコード内のコメントとして扱い、生成されるドキュメントからは除外されます。

この変更の利点は以下の通りです。

1.  **`godoc`出力の一貫性**: `godoc`によって生成されるドキュメントが、`//sys`行の有無に左右されず、よりクリーンで一貫性のあるものになります。
2.  **ドキュメントの正確性**: `//sys`行はシステムコールに関するメタ情報であり、Go関数の公開APIとしてのドキュメンテーションには必ずしも必要ありません。この変更により、`godoc`はGo関数の本来の目的をより正確に反映したドキュメントを生成できます。
3.  **ソースコードの可読性の維持**: `//sys`行自体は、ソースコードを直接読む開発者にとって、Go関数がどのシステムコールに対応しているかを理解する上で非常に有用な情報です。この変更は、これらの行を削除することなく、その情報をソースコード内に保持しています。

このように、このコミットはGoのドキュメンテーションシステムの特性を巧みに利用し、`godoc`の出力品質を向上させつつ、ソースコードの有用なメタ情報を維持するという、シンプルながらも効果的な改善を実現しています。

## 関連リンク

*   Go CL 7324056: [https://golang.org/cl/7324056](https://golang.org/cl/7324056)

## 参考にした情報源リンク

*   Go Doc Comments: [https://go.dev/blog/godoc](https://go.dev/blog/godoc)
*   Go `syscall` package documentation: [https://pkg.go.dev/syscall](https://pkg.go.dev/syscall)
*   Go `godoc` command documentation: [https://pkg.go.dev/cmd/godoc](https://pkg.go.dev/cmd/godoc)
*   Go `doc` package documentation: [https://pkg.go.dev/go/doc](https://pkg.go.dev/go/doc)
*   Go `parser` package documentation (for understanding how comments are parsed): [https://pkg.go.dev/go/parser](https://pkg.go.dev/go/parser)
*   Go `ast` package documentation (for understanding Abstract Syntax Trees): [https://pkg.go.dev/go/ast](https://pkg.go.dev/go/ast)