[インデックス 18501] ファイルの概要
このコミットは、Go言語のランタイムの一部であるlib9
ライブラリにおける、Plan 9環境での不整合とコンパイラの警告を修正することを目的としています。具体的には、到達不能なコードや未使用の変数に関する警告の解消、およびPlan 9と非Plan 9環境でのビルドの差異を適切に扱うための変更が含まれています。
コミット
commit 705d7c164fa61181f2f943fb2541b39b39ced637
Author: David du Colombier <0intro@gmail.com>
Date: Thu Feb 13 20:05:55 2014 +0100
lib9: fix inconsistencies and warnings on Plan 9
warning: src/lib9/fmt/dorfmt.c:64 unreachable code RETURN
warning: src/lib9/fmt/fltfmt.c:184 set and not used: p
warning: src/lib9/utf/utflen.c:35 unreachable code RETURN
warning: src/lib9/utf/utfrrune.c:45 unreachable code RETURN
warning: src/lib9/utf/utfrune.c:44 unreachable code RETURN
LGTM=rsc
R=rsc, iant, gobot
CC=golang-codereviews
https://golang.org/cl/57170052
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/705d7c164fa61181f2f943fb2541b39b39ced637
元コミット内容
このコミットは、lib9
ライブラリにおける以下の問題に対処しています。
- Plan 9環境での不整合: Plan 9オペレーティングシステム上でのビルド時に発生する問題。
- コンパイラの警告:
src/lib9/fmt/dorfmt.c:64
: 到達不能なコード(unreachable code RETURN
)src/lib9/fmt/fltfmt.c:184
: 設定されたが使用されていない変数(set and not used: p
)src/lib9/utf/utflen.c:35
: 到達不能なコード(unreachable code RETURN
)src/lib9/utf/utfrrune.c:45
: 到達不能なコード(unreachable code RETURN
)src/lib9/utf/utfrune.c:44
: 到達不能なコード(unreachable code RETURN
)
これらの警告は、コードの品質と保守性に影響を与える可能性があり、修正が必要とされていました。
変更の背景
Go言語は、その設計思想の一部として、シンプルさと堅牢性を重視しています。コンパイラの警告は、潜在的なバグや非効率なコード、あるいは意図しない動作を示す可能性があるため、これらを解消することはコードベースの健全性を保つ上で重要です。
このコミットで修正されているlib9
は、Go言語の初期段階において、Plan 9オペレーティングシステムから移植されたC言語のライブラリ群です。Plan 9はベル研究所で開発された分散オペレーティングシステムであり、その設計思想はGo言語にも大きな影響を与えています。lib9
は、Goのランタイムや標準ライブラリの一部として、ファイルシステム操作、文字列処理、フォーマットなど、低レベルの機能を提供していました。
警告の発生は、主に以下の理由が考えられます。
- コードの進化とデッドコード: 時間の経過とともにコードが変更され、以前は到達可能だったコードパスが、新しいロジックの導入によって到達不能になった。
- 未使用変数: 変数が宣言され、値が設定されたものの、その後の処理で一度も使用されなかった。これは、リファクタリングの過程で変数の必要性がなくなった場合や、単なるプログラミングミスによって発生します。
- Plan 9固有のビルド問題: Go言語はクロスプラットフォームを強く意識していますが、特定のOS(この場合はPlan 9)に特化したコードやビルド設定が存在する場合、他のOSとの間で不整合が生じることがあります。特に、C言語のヘッダーファイルのインクルードや、ポインタの型変換に関する問題は、異なるコンパイラや環境で顕在化しやすいです。
これらの問題を修正することで、Go言語のコードベース全体の品質が向上し、特にPlan 9環境でのビルドの安定性が確保されます。
前提知識の解説
1. Plan 9とlib9
- Plan 9: ベル研究所で開発された分散オペレーティングシステム。Unixの設計思想をさらに推し進め、すべてのリソースをファイルとして扱うという徹底した思想が特徴です。Go言語の設計者の一部(Rob Pike, Ken Thompsonなど)はPlan 9の開発にも携わっており、Go言語にはPlan 9の思想が色濃く反映されています。
lib9
: Plan 9のユーザー空間ライブラリ群を指します。Go言語の初期のランタイムや標準ライブラリの一部は、このlib9
のC言語コードをベースに移植・再実装されました。低レベルのシステムコール、文字列操作、フォーマット、UTF-8処理など、基本的な機能を提供します。
2. C言語におけるコンパイラ警告
unreachable code
(到達不能なコード): プログラムの実行フローが、特定のコードブロックに決して到達しないことを意味します。これは通常、return
文、break
文、continue
文、または無限ループの後に続くコードで発生します。コンパイラは、このコードが実行されることがないため、警告を発します。これはデッドコードであり、削除するか、ロジックを修正する必要があります。set and not used
(設定されたが使用されていない変数): 変数が宣言され、初期値が設定されたにもかかわらず、その変数の値がプログラムのどこでも読み取られない場合に発生します。これは、プログラミングミス、またはリファクタリングの際に変数が不要になったにもかかわらず削除されなかった場合に起こります。未使用の変数はメモリを無駄にし、コードの可読性を低下させる可能性があります。
3. Goビルドタグ (// +build
)
Go言語には、特定のファイルが特定の環境でのみコンパイルされるように制御するための「ビルドタグ」という仕組みがあります。ファイルの先頭に// +build tag
のようなコメントを記述することで、そのファイルがコンパイルされる条件を指定できます。
// +build plan9
: このタグが付いているファイルは、GoがPlan 9環境向けにビルドされる場合にのみコンパイルされます。// +build !plan9
: このタグが付いているファイルは、GoがPlan 9以外の環境向けにビルドされる場合にのみコンパイルされます。
これにより、OS固有のコードを分離し、クロスプラットフォーム対応を容易にしています。
4. C言語の型変換とポインタ
uintptr_t
: C言語の標準ライブラリ<stdint.h>
で定義されている型で、ポインタを保持できる十分な大きさを持つ符号なし整数型です。ポインタと整数の間で安全に変換を行うために使用されます。void*
: 任意の型のデータへのポインタを表す汎用ポインタ型です。void*
から他のポインタ型への変換は暗黙的に行われることがありますが、明示的なキャストが推奨されます。uintptr
: Go言語におけるuintptr
型は、ポインタを保持できる十分な大きさを持つ符号なし整数型です。C言語のuintptr_t
に相当します。Goでは、ポインタとuintptr
の間で直接的な変換は許可されておらず、unsafe
パッケージを使用する必要があります。このコミットではC言語のコードを扱っているため、C言語のuintptr_t
の概念が適用されます。
5. C言語の標準ライブラリ
<string.h>
: C言語の標準ライブラリで、文字列操作関数(strlen
,strcpy
,memcpy
など)を提供します。<u.h>
: Plan 9のユーザー空間プログラミングにおける標準ヘッダーファイルの一つで、基本的な型定義やユーティリティ関数が含まれます。<libc.h>
: Plan 9のユーザー空間プログラミングにおける標準ヘッダーファイルの一つで、一般的なライブラリ関数が含まれます。_BSD_SOURCE
: BSD系のシステムコールやライブラリ関数を有効にするためのマクロです。通常、#define _BSD_SOURCE
をインクルードする前に定義します。
技術的詳細
このコミットは、複数のファイルにわたる小規模な修正の集合体であり、それぞれが特定の警告や不整合に対処しています。
-
src/lib9/errstr.c
:// +build !plan9
タグが追加されました。これは、このファイルがPlan 9以外の環境でのみコンパイルされるべきであることを示します。errstr.c
は、エラー文字列の処理に関するコードを含んでおり、Plan 9とそれ以外のOSでエラー処理のメカニズムが異なるため、条件付きコンパイルが必要になります。#include <string.h>
が削除されました。このファイル内でstring.h
の関数が直接使用されていないか、または他のヘッダーファイル(例えば<libc.h>
)を通じて必要な関数が提供されるようになったため、冗長なインクルードが削除されました。
-
src/lib9/fmt/dorfmt.c
:dorfmt
関数の末尾にあったreturn 0;
が削除されました。元のコードでは、このreturn 0;
は常に到達不能でした。これは、関数内のif(fmt == nil) return -1;
の後に続くコードが、fmt
がnil
でない場合にのみ実行され、そのパスのどこかで関数が終了するためです。この修正により、「unreachable code RETURN」警告が解消されます。
-
src/lib9/fmt/errfmt.c
:- このファイルは新規追加されました。
// +build plan9
タグが付与されており、Plan 9環境でのみコンパイルされます。__errfmt
関数が定義されており、これはPlan 9のエラー文字列を取得し、フォーマットするためのものです。rerrstr(buf, sizeof buf)
: Plan 9固有の関数で、システムのエラー文字列をbuf
に読み込みます。__fmtcpy(f, buf, utflen(buf), strlen(buf))
: フォーマット構造体f
にエラー文字列buf
をコピーします。utflen
はUTF-8文字列の文字数を、strlen
はバイト数を返します。これは、UTF-8対応のエラーメッセージ処理を示唆しています。
-
src/lib9/fmt/fltfmt.c
:xsub1
関数のabort()
呼び出しの後にreturn 0;
が追加されました。abort()
はプログラムを異常終了させる関数ですが、コンパイラは関数の戻り値の型がvoid
でない場合、すべてのコードパスでreturn
文があることを期待します。abort()
が呼び出された後、実際にはコードは実行されませんが、コンパイラの警告を抑制するために形式的にreturn
が追加されました。xfmtexp
関数で、*p++ = '\0';
が*p = '\0';
に修正されました。元のコードでは、ヌル終端文字を書き込んだ後にポインタp
がインクリメントされていましたが、これは不要であり、場合によってはバッファオーバーランの潜在的な原因となる可能性がありました。修正により、ヌル終端文字を書き込んだ後もポインタp
は元の位置に留まります。xdtoa
関数で、変数宣言の順序が変更されました。int oerrno;
がint d, e2, e, ee, i, ndigit;
の後に移動しました。これは「set and not used: p」警告とは直接関係ありませんが、コードの可読性や特定のコンパイラでの警告抑制のために行われた可能性があります。元のコミットメッセージの警告はp
に関するものでしたが、この変更はoerrno
に関するものであり、別の警告か、あるいは関連するクリーンアップの一部と考えられます。
-
src/lib9/fmt/fmtfd.c
:f->farg = (void*)(uintptr_t)fd;
がf->farg = (void*)(uintptr)fd;
に修正されました。これは、C言語のuintptr_t
型ではなく、Go言語のuintptr
型(またはそれに相当する型)へのキャストを意図している可能性があります。uintptr_t
はC99で導入された型ですが、Goのコードベースではuintptr
という用語が使われることが多いため、表記の統一を図ったか、あるいは特定のコンパイラ環境での警告を避けるための変更と考えられます。ポインタを整数に変換し、それを再度ポインタに変換する際に、適切な型キャストを行うことで、ポインタのサイズに関する警告や不整合を避けることができます。
-
src/lib9/utf/utfecpy.c
,src/lib9/utf/utfrrune.c
,src/lib9/utf/utfrune.c
,src/lib9/utf/utfutf.c
:- これらのファイルでは、
#define _BSD_SOURCE 1
と#include <string.h>
が削除され、代わりに#include <u.h>
と#include <libc.h>
が追加されました。これは、これらのUTF-8処理関連のファイルが、BSD固有の定義や標準Cライブラリのstring.h
に依存するのではなく、Plan 9の標準ヘッダーファイルに依存するように変更されたことを意味します。これにより、Plan 9環境でのビルドの互換性が向上し、よりPlan 9ネイティブなアプローチに移行したことを示しています。
- これらのファイルでは、
-
src/lib9/utf/utflen.c
:utflen
関数の末尾にあったreturn 0;
が削除されました。dorfmt.c
と同様に、このreturn 0;
は常に到達不能でした。関数内のループが終了すると、n
が返されるべきであり、このreturn 0;
はデッドコードでした。この修正により、「unreachable code RETURN」警告が解消されます。
コアとなるコードの変更箇所
1. 到達不能なコードの削除 (src/lib9/fmt/dorfmt.c
, src/lib9/utf/utflen.c
)
--- a/src/lib9/fmt/dorfmt.c
+++ b/src/lib9/fmt/dorfmt.c
@@ -61,5 +61,4 @@ dorfmt(Fmt *f, const Rune *fmt)
\tif(fmt == nil)
\t\treturn -1;
}\n-\treturn 0;\t\t/* not reached */
}\n
--- a/src/lib9/utf/utflen.c
+++ b/src/lib9/utf/utflen.c
@@ -32,5 +32,4 @@ utflen(const char *s)
\t\ts += chartorune(&rune, s);
\t\tn++;
}\n-\treturn 0;\n
}\n
2. Plan 9固有のエラーフォーマットの追加 (src/lib9/fmt/errfmt.c
)
--- /dev/null
+++ b/src/lib9/fmt/errfmt.c
@@ -0,0 +1,32 @@
+// +build plan9
+
+/*
+ * The authors of this software are Rob Pike and Ken Thompson,
+ * with contributions from Mike Burrows and Sean Dorward.
+ *
+ * Copyright (c) 2002-2006 by Lucent Technologies.
+ * Portions Copyright (c) 2004 Google Inc.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose without fee is hereby granted, provided that this entire notice
+ * is included in all copies of any software which is or includes a copy
+ * or modification of this software and in all copies of the supporting
+ * documentation for such software.
+ * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTY. IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES
+ * NOR GOOGLE INC MAKE ANY REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING
+ * THE MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
+ */
+
+#include <u.h>
+#include <libc.h>
+#include "fmtdef.h"
+
+int
+__errfmt(Fmt *f)
+{
+ char buf[ERRMAX];
+
+ rerrstr(buf, sizeof buf);
+ return __fmtcpy(f, buf, utflen(buf), strlen(buf));
+}
3. ヘッダーファイルの変更とビルドタグの追加 (src/lib9/errstr.c
, src/lib9/utf/utfecpy.c
など)
--- a/src/lib9/errstr.c
+++ b/src/lib9/errstr.c
@@ -1,3 +1,5 @@
+// +build !plan9
+
/*
Plan 9 from User Space src/lib9/errstr.c
http://code.swtch.com/plan9port/src/tip/src/lib9/errstr.c
@@ -32,7 +34,6 @@ THE SOFTWARE.
#include <u.h>
#include <errno.h>
-#include <string.h>
#include <libc.h>\n
--- a/src/lib9/utf/utfecpy.c
+++ b/src/lib9/utf/utfecpy.c
@@ -11,8 +11,8 @@
* REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
* OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
*/
-#define _BSD_SOURCE 1
-#include <string.h>
+#include <u.h>
+#include <libc.h>\n
#include "utf.h"\n
#include "utfdef.h"\n
コアとなるコードの解説
1. 到達不能なコードの削除
dorfmt
関数とutflen
関数からreturn 0;
が削除されたのは、これらのreturn
文がコードの実行パス上、決して到達しない位置にあったためです。C言語のコンパイラは、このようなデッドコードに対して警告を発します。関数が値を返す場合、すべての可能な実行パスでreturn
文が存在する必要がありますが、このケースでは、それより前のreturn
文やループの終了によって、このreturn 0;
に到達することがありませんでした。これにより、コンパイラの警告が解消され、コードがよりクリーンになりました。
2. Plan 9固有のエラーフォーマットの追加
src/lib9/fmt/errfmt.c
の追加は、Plan 9環境に特化したエラーメッセージのフォーマット処理を導入したことを示しています。
// +build plan9
タグにより、このファイルはPlan 9向けビルドでのみコンパイルされます。__errfmt
関数は、Plan 9のシステムコールrerrstr
を使用してエラー文字列を取得し、それを__fmtcpy
関数でフォーマットバッファにコピーします。utflen(buf)
とstrlen(buf)
の両方を使用していることから、エラーメッセージがUTF-8エンコードされている可能性があり、文字数とバイト数の両方を考慮して正確に処理していることがわかります。 この変更により、Plan 9環境でのエラー報告が適切に行われるようになります。
3. ヘッダーファイルの変更とビルドタグの追加
src/lib9/errstr.c
に// +build !plan9
タグが追加され、#include <string.h>
が削除されたことは、このファイルがPlan 9以外の環境向けのエラー文字列処理を担当し、Plan 9固有のヘッダーファイルや機能に依存しないことを明確にしています。
また、src/lib9/utf
ディレクトリ内の複数のファイルで_BSD_SOURCE
マクロと<string.h>
のインクルードが削除され、代わりに<u.h>
と<libc.h>
が追加されたことは、これらのUTF-8処理関連のコードが、BSD互換性レイヤーや標準Cライブラリではなく、Plan 9のネイティブなライブラリとヘッダーに依存するように変更されたことを意味します。これにより、Plan 9環境でのビルドの整合性が向上し、よりPlan 9の慣習に沿ったコードベースになりました。
これらの変更は全体として、Go言語のlib9
部分が、各ターゲットOS(特にPlan 9)の特性に合わせて適切にビルドされ、コンパイラの警告を解消し、コードの品質と保守性を向上させることを目的としています。
関連リンク
参考にした情報源リンク
- Go言語の公式ドキュメント
- Plan 9 from User Spaceのソースコード
- C言語のコンパイラ警告に関する一般的な情報源 (例: GCCのドキュメントなど)
uintptr_t
に関するC言語のドキュメント