[インデックス 1125] ファイルの概要
このコミットは、Go言語の初期開発段階において、ビルドシステムとコンパイラの改善を目的としたものです。具体的には、コードカバレッジツール(cov
)とプロファイリングツール(prof
)をデフォルトのビルドプロセスに含めるように変更し、同時にコンパイラの警告をクリーンアップするための修正を行っています。これにより、開発者がGoプログラムの品質とパフォーマンスをより簡単に測定・分析できるようになることを目指しています。
コミット
commit f8b20e40838e90f6ac0eae383749189bac73b73c
Author: Russ Cox <rsc@golang.org>
Date: Fri Nov 14 10:57:48 2008 -0800
add cov, prof to default build; clean up compiler warnings
R=r
DELTA=8 (1 added, 0 deleted, 7 changed)
OCL=19245
CL=19245
---
src/cmd/cc/cc.h | 2 +-\
src/cmd/clean.bash | 2 +-\
src/cmd/make.bash | 2 +-\
src/cmd/prof/main.c | 6 +++---\
src/lib/reflect/typestring.c | 2 +-\
src/runtime/runtime.c | 1 +
6 files changed, 8 insertions(+), 7 deletions(-)
diff --git a/src/cmd/cc/cc.h b/src/cmd/cc/cc.h
index b453755947..eefe5bed9e 100644
--- a/src/cmd/cc/cc.h
+++ b/src/cmd/cc/cc.h
@@ -61,7 +61,7 @@ typedef struct Bits Bits;\
#define NTERM 10
#define MAXALIGN 7
-#define SIGN(n) ((vlong)1<<(n-1))\
+#define SIGN(n) ((uvlong)1<<(n-1))\
#define MASK(n) (SIGN(n)|(SIGN(n)-1))\
#define BITS 5
diff --git a/src/cmd/clean.bash b/src/cmd/clean.bash
index 14151d86d6..41f4917d9e 100644
--- a/src/cmd/clean.bash
+++ b/src/cmd/clean.bash
@@ -3,7 +3,7 @@
# Use of this source code is governed by a BSD-style
# license that can be found in the LICENSE file.
-for i in 6l 6a 6c 6g gc cc ar db nm blyacc acid\
+for i in 6l 6a 6c 6g gc cc ar db nm blyacc acid cov prof\
do
cd $i
make clean
diff --git a/src/cmd/make.bash b/src/cmd/make.bash
index 103b17fa6f..980659ff72 100644
--- a/src/cmd/make.bash
+++ b/src/cmd/make.bash
@@ -12,7 +12,7 @@ bash mkenam
make enam.o
cd ..
-for i in cc 6l 6a 6c gc 6g ar db nm blyacc acid\
+for i in cc 6l 6a 6c gc 6g ar db nm blyacc acid cov prof\
do
echo; echo; echo %%%% making $i %%%%; echo
cd $i
diff --git a/src/cmd/prof/main.c b/src/cmd/prof/main.c
index a4223e75a8..c4380b9b38 100644
--- a/src/cmd/prof/main.c
+++ b/src/cmd/prof/main.c
@@ -321,13 +321,13 @@ main(int argc, char *argv[])
collapse = 0;
break;
case 'd':
-\t\tdelta_msec = atoi(EARGF(Usage));\
+\t\tdelta_msec = atoi(EARGF(Usage()));\
break;
case 't':
-\t\ttotal_sec = atoi(EARGF(Usage));\
+\t\ttotal_sec = atoi(EARGF(Usage()));\
break;
case 'p':
-\t\tpid = atoi(EARGF(Usage));\
+\t\tpid = atoi(EARGF(Usage()));\
break;
case 'f':
functions = 1;
diff --git a/src/lib/reflect/typestring.c b/src/lib/reflect/typestring.c
index a5e6398ad3..07144b3e06 100644
--- a/src/lib/reflect/typestring.c
+++ b/src/lib/reflect/typestring.c
@@ -4,7 +4,7 @@
extern char gotypestrings[]; // really a go String, but we don't have the definition here
-void FLUSH(void *v) { }\
+void FLUSH(void*) { }\
void reflect·typestrings(void *s) {
s = gotypestrings;
diff --git a/src/runtime/runtime.c b/src/runtime/runtime.c
index ea2c432396..766f16f6d4 100644
--- a/src/runtime/runtime.c
+++ b/src/runtime/runtime.c
@@ -674,6 +674,7 @@ memcopy(uint32 s, void *a, void *b)
static uint64
stringhash(uint32 s, string *a)
{
+\tUSED(s);\
return memhash((*a)->len, (*a)->str);
}
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/f8b20e40838e90f6ac0eae383749189bac73b73c
元コミット内容
このコミットの目的は、Go言語のビルドプロセスにcov
(コードカバレッジツール)とprof
(プロファイリングツール)をデフォルトで含めるようにすること、そしてコンパイラが生成する警告をクリーンアップすることです。これにより、Go開発者がコードの品質とパフォーマンスをより容易に評価できるようになり、また、コンパイラ警告のノイズを減らすことで、より重要な問題に集中できるようになります。
変更の背景
このコミットが行われた2008年11月は、Go言語がまだ一般に公開される前の、活発な初期開発段階にありました。この時期のGo言語は、コンパイラ、ランタイム、標準ライブラリなど、基盤となるコンポーネメントが構築されている最中でした。
このような初期段階では、開発効率とコード品質の確保が非常に重要になります。cov
やprof
といったツールは、コードのテスト網羅率を測定したり、プログラムの実行時間やメモリ使用量を分析したりするために不可欠です。これらをデフォルトのビルドに含めることで、開発者はGo言語のツールチェインに最初からこれらの機能が組み込まれていることを期待でき、開発プロセス全体で品質とパフォーマンスを意識した開発が可能になります。
また、コンパイラの警告は、潜在的なバグや非効率なコードを示唆することがありますが、過剰な警告は開発者の注意を散漫にさせ、本当に重要な警告を見落とす原因にもなります。そのため、コンパイラ警告をクリーンアップすることは、開発体験を向上させ、コードベースの健全性を維持するために重要な作業でした。
前提知識の解説
Go言語の初期ビルドシステム
Go言語の初期のビルドシステムは、現在のGo Modulesやgo build
コマンドのような洗練されたものではなく、シェルスクリプト(特にbash
スクリプト)とmake
コマンドを組み合わせて構築されていました。src/cmd/make.bash
やsrc/cmd/clean.bash
のようなファイルは、Goのコンパイラ、リンカ、アセンブラなどのツール群をビルド・クリーンアップするためのスクリプトでした。
cov
とprof
cov
(Code Coverage Tool): コードカバレッジツールは、テストがソースコードのどの部分を実行したかを測定します。これにより、テストスイートがどれだけ広範囲のコードをカバーしているかを把握し、テストが不足している領域を特定するのに役立ちます。Go言語では、後にgo test -cover
として統合される機能の初期段階に相当します。prof
(Profiling Tool): プロファイリングツールは、プログラムの実行中にそのパフォーマンス特性(CPU使用率、メモリ割り当て、関数呼び出しの頻度など)を収集・分析します。これにより、プログラムのボトルネックを特定し、最適化の対象となる領域を見つけることができます。Go言語では、後にgo tool pprof
として提供される機能の初期段階に相当します。
vlong
とuvlong
(C言語における型)
C言語において、long long
型は64ビット整数を表すことが一般的です。
vlong
:signed long long
を意味するカスタム型定義である可能性が高いです。符号付き64ビット整数です。uvlong
:unsigned long long
を意味するカスタム型定義である可能性が高いです。符号なし64ビット整数です。
このコミットでは、src/cmd/cc/cc.h
でSIGN(n)
マクロの型キャストをvlong
からuvlong
に変更しています。これは、ビットシフト演算の結果が負になることを防ぐため、または符号なしの最大値を正しく表現するために行われたと考えられます。特に、1 << (n-1)
のようなビットシフト演算では、n-1
が63の場合、符号付き整数でシフトするとオーバーフローや未定義動作を引き起こす可能性があります。uvlong
にキャストすることで、結果が常に符号なしとして扱われ、より大きな正の値を表現できるようになります。
EARGF(Usage)
とEARGF(Usage())
(C言語におけるマクロ/関数呼び出し)
EARGF
は、おそらくコマンドライン引数を解析するためのマクロまたは関数です。Usage
は、プログラムの正しい使用方法を示す文字列や関数への参照であると考えられます。
EARGF(Usage)
:Usage
が文字列リテラルや変数である場合、その値を直接EARGF
に渡しています。EARGF(Usage())
:Usage
が関数である場合、Usage()
はUsage
関数の戻り値をEARGF
に渡しています。
このコミットでは、src/cmd/prof/main.c
でEARGF(Usage)
をEARGF(Usage())
に変更しています。これは、Usage
が実際には関数であり、その戻り値(おそらく使用方法を示す文字列)をEARGF
に渡す必要があったため、コンパイラ警告を解消するために修正されたと考えられます。
void FLUSH(void *v)
とvoid FLUSH(void*)
(C言語における関数宣言)
C言語では、関数引数の名前は省略可能です。
void FLUSH(void *v)
:v
という名前のvoid
ポインタを引数にとる関数宣言です。void FLUSH(void*)
:void
ポインタを引数にとる関数宣言ですが、引数名が省略されています。
このコミットでは、src/lib/reflect/typestring.c
でvoid FLUSH(void *v)
をvoid FLUSH(void*)
に変更しています。これは、関数内で引数v
が使用されていないため、コンパイラが「未使用の引数」に関する警告を出すのを避けるための一般的な慣習です。引数名を省略することで、その引数が意図的に使用されていないことを明示し、警告を抑制します。
USED(s)
マクロ (C言語における未使用変数警告の抑制)
USED
マクロは、C言語でコンパイラが未使用の変数に対して警告を出すのを抑制するために使用されることが多いです。典型的な実装は以下のようになります。
#define USED(x) (void)(x)
このマクロは、引数x
をvoid
にキャストすることで、その変数が「使用された」とコンパイラに認識させ、警告を抑制します。これは、特定の変数がデバッグ目的や将来の拡張のために残されているが、現在のコードでは直接使用されていない場合に便利です。
このコミットでは、src/runtime/runtime.c
でUSED(s);
が追加されています。これは、stringhash
関数内で引数s
が直接使用されていないため、コンパイラ警告を抑制するために追加されたと考えられます。
技術的詳細
src/cmd/cc/cc.h
の変更
- 変更内容:
#define SIGN(n) ((vlong)1<<(n-1))
を#define SIGN(n) ((uvlong)1<<(n-1))
に変更。 - 詳細:
SIGN(n)
マクロは、おそらく特定のビット位置に1を立てる(ビットマスクを生成する)ために使用されます。元のコードではvlong
(符号付き64ビット整数)にキャストしていましたが、n-1
が63の場合、1 << 63
は符号付き64ビット整数では負の値(最上位ビットが符号ビットとして解釈されるため)になるか、未定義動作を引き起こす可能性があります。これをuvlong
(符号なし64ビット整数)にキャストすることで、結果が常に符号なしの正の値として扱われ、ビットマスクが意図通りに機能するようになります。これは、コンパイラ警告の解消と、より堅牢なビット演算の実現に貢献します。
src/cmd/clean.bash
とsrc/cmd/make.bash
の変更
- 変更内容:
for i in ...
のリストにcov
とprof
を追加。 - 詳細: これらのシェルスクリプトは、Go言語のツールチェインをビルド(
make.bash
)およびクリーンアップ(clean.bash
)するためのものです。cov
とprof
をこのリストに追加することで、これらのツールがGoのデフォルトのビルドプロセスの一部としてコンパイルされ、またmake clean
コマンドで適切にクリーンアップされるようになります。これにより、Go開発者は追加の設定なしにこれらのパフォーマンス・品質分析ツールを利用できるようになります。
src/cmd/prof/main.c
の変更
- 変更内容:
atoi(EARGF(Usage))
をatoi(EARGF(Usage()))
に変更。 - 詳細:
EARGF
マクロが引数として関数ポインタではなく、関数の戻り値を期待していることを示唆しています。元のコードではUsage
という関数名を直接渡していましたが、これはコンパイラによっては警告(例: "passing 'int (*)(void)' to parameter of type 'const char *'" のような警告)を生成する可能性があります。Usage()
とすることで、Usage
関数の実行結果(おそらくエラーメッセージや使用方法の文字列)がEARGF
に渡され、コンパイラ警告が解消されます。これは、C言語の関数ポインタと関数呼び出しのセマンティクスに関する厳密な型チェックに対応するための修正です。
src/lib/reflect/typestring.c
の変更
- 変更内容:
void FLUSH(void *v) { }
をvoid FLUSH(void*) { }
に変更。 - 詳細:
FLUSH
関数は、引数v
を受け取りますが、その関数本体ではv
が使用されていません。C言語のコンパイラは、このような未使用の引数に対して警告を出すことがあります。引数名を省略することで、開発者がその引数が意図的に使用されていないことをコンパイラに伝え、警告を抑制する一般的な方法です。これは、コードのクリーンさを保ち、不必要な警告を排除するための修正です。
src/runtime/runtime.c
の変更
- 変更内容:
stringhash
関数内にUSED(s);
を追加。 - 詳細:
stringhash
関数はuint32 s
を引数として受け取りますが、関数本体ではこのs
が直接使用されていません。USED(s);
マクロを追加することで、コンパイラがs
が使用されていると認識し、未使用変数に関する警告を抑制します。これは、コンパイラ警告をクリーンアップするための一貫したアプローチの一部です。
コアとなるコードの変更箇所
src/cmd/cc/cc.h
:-#define SIGN(n) ((vlong)1<<(n-1)) +#define SIGN(n) ((uvlong)1<<(n-1))
src/cmd/clean.bash
:-for i in 6l 6a 6c 6g gc cc ar db nm blyacc acid +for i in 6l 6a 6c 6g gc cc ar db nm blyacc acid cov prof
src/cmd/make.bash
:-for i in cc 6l 6a 6c gc 6g ar db nm blyacc acid +for i in cc 6l 6a 6c gc 6g ar db nm blyacc acid cov prof
src/cmd/prof/main.c
:-\t\tdelta_msec = atoi(EARGF(Usage)); +\t\tdelta_msec = atoi(EARGF(Usage())); // ... (同様の変更が2箇所)
src/lib/reflect/typestring.c
:-void FLUSH(void *v) { } +void FLUSH(void*) { }
src/runtime/runtime.c
:static uint64 stringhash(uint32 s, string *a) { +\tUSED(s); return memhash((*a)->len, (*a)->str); }
コアとなるコードの解説
このコミットのコアとなる変更は、大きく分けて2つの目的を持っています。
-
cov
とprof
のビルドプロセスへの統合:src/cmd/clean.bash
とsrc/cmd/make.bash
における変更は、Go言語のビルドシステムにcov
とprof
という新しいツールを組み込むことを意味します。これにより、これらのツールはGoの標準的なビルド手順でコンパイルされ、開発者がGoのソースコードからビルドする際に自動的に利用可能になります。これは、Go言語が初期段階からコード品質とパフォーマンス分析を重視していたことを示しており、開発者がこれらのツールを容易に利用できる環境を整備する意図があります。
-
コンパイラ警告のクリーンアップ:
src/cmd/cc/cc.h
でのvlong
からuvlong
への型キャストの変更は、ビットシフト演算のセマンティクスを明確にし、潜在的な未定義動作や符号に関する問題を回避するためのものです。これにより、コンパイラがより正確なコードを生成できるようになり、警告も抑制されます。src/cmd/prof/main.c
でのEARGF(Usage)
からEARGF(Usage())
への変更は、C言語の関数呼び出しの正しい構文に従うことで、コンパイラが「関数ポインタを期待される型に変換できない」といった警告を出すのを防ぎます。これは、コードの正確性を高め、コンパイラ警告のノイズを減らすための典型的な修正です。src/lib/reflect/typestring.c
での未使用引数名の省略と、src/runtime/runtime.c
でのUSED(s);
の追加は、いずれもC言語のコンパイラが未使用の変数や引数に対して出す警告を抑制するためのものです。これらの修正は、コードの機能には影響を与えませんが、コンパイラ出力のクリーンさを保ち、開発者が本当に重要な警告に集中できるようにするために重要です。
これらの変更は、Go言語の初期開発における実用性と堅牢性を高めるための、細部にわたる配慮を示しています。
関連リンク
- Go言語の初期開発に関する情報: https://go.dev/doc/history
- Go言語のプロファイリングツール (
pprof
) の概要: https://go.dev/blog/pprof - Go言語のコードカバレッジ: https://go.dev/blog/cover
参考にした情報源リンク
- Go言語の公式ドキュメント
- C言語の型とビット演算に関する一般的な知識
- C言語のコンパイラ警告と抑制に関する一般的な慣習
- Gitのコミット履歴と差分表示の分析