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

[インデックス 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言語は、コンパイラ、ランタイム、標準ライブラリなど、基盤となるコンポーネメントが構築されている最中でした。

このような初期段階では、開発効率とコード品質の確保が非常に重要になります。covprofといったツールは、コードのテスト網羅率を測定したり、プログラムの実行時間やメモリ使用量を分析したりするために不可欠です。これらをデフォルトのビルドに含めることで、開発者はGo言語のツールチェインに最初からこれらの機能が組み込まれていることを期待でき、開発プロセス全体で品質とパフォーマンスを意識した開発が可能になります。

また、コンパイラの警告は、潜在的なバグや非効率なコードを示唆することがありますが、過剰な警告は開発者の注意を散漫にさせ、本当に重要な警告を見落とす原因にもなります。そのため、コンパイラ警告をクリーンアップすることは、開発体験を向上させ、コードベースの健全性を維持するために重要な作業でした。

前提知識の解説

Go言語の初期ビルドシステム

Go言語の初期のビルドシステムは、現在のGo Modulesやgo buildコマンドのような洗練されたものではなく、シェルスクリプト(特にbashスクリプト)とmakeコマンドを組み合わせて構築されていました。src/cmd/make.bashsrc/cmd/clean.bashのようなファイルは、Goのコンパイラ、リンカ、アセンブラなどのツール群をビルド・クリーンアップするためのスクリプトでした。

covprof

  • cov (Code Coverage Tool): コードカバレッジツールは、テストがソースコードのどの部分を実行したかを測定します。これにより、テストスイートがどれだけ広範囲のコードをカバーしているかを把握し、テストが不足している領域を特定するのに役立ちます。Go言語では、後にgo test -coverとして統合される機能の初期段階に相当します。
  • prof (Profiling Tool): プロファイリングツールは、プログラムの実行中にそのパフォーマンス特性(CPU使用率、メモリ割り当て、関数呼び出しの頻度など)を収集・分析します。これにより、プログラムのボトルネックを特定し、最適化の対象となる領域を見つけることができます。Go言語では、後にgo tool pprofとして提供される機能の初期段階に相当します。

vlonguvlong (C言語における型)

C言語において、long long型は64ビット整数を表すことが一般的です。

  • vlong: signed long longを意味するカスタム型定義である可能性が高いです。符号付き64ビット整数です。
  • uvlong: unsigned long longを意味するカスタム型定義である可能性が高いです。符号なし64ビット整数です。

このコミットでは、src/cmd/cc/cc.hSIGN(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.cEARGF(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.cvoid FLUSH(void *v)void FLUSH(void*)に変更しています。これは、関数内で引数vが使用されていないため、コンパイラが「未使用の引数」に関する警告を出すのを避けるための一般的な慣習です。引数名を省略することで、その引数が意図的に使用されていないことを明示し、警告を抑制します。

USED(s)マクロ (C言語における未使用変数警告の抑制)

USEDマクロは、C言語でコンパイラが未使用の変数に対して警告を出すのを抑制するために使用されることが多いです。典型的な実装は以下のようになります。

#define USED(x) (void)(x)

このマクロは、引数xvoidにキャストすることで、その変数が「使用された」とコンパイラに認識させ、警告を抑制します。これは、特定の変数がデバッグ目的や将来の拡張のために残されているが、現在のコードでは直接使用されていない場合に便利です。

このコミットでは、src/runtime/runtime.cUSED(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.bashsrc/cmd/make.bashの変更

  • 変更内容: for i in ... のリストに covprof を追加。
  • 詳細: これらのシェルスクリプトは、Go言語のツールチェインをビルド(make.bash)およびクリーンアップ(clean.bash)するためのものです。covprofをこのリストに追加することで、これらのツールが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つの目的を持っています。

  1. covprofのビルドプロセスへの統合:

    • src/cmd/clean.bashsrc/cmd/make.bashにおける変更は、Go言語のビルドシステムにcovprofという新しいツールを組み込むことを意味します。これにより、これらのツールはGoの標準的なビルド手順でコンパイルされ、開発者がGoのソースコードからビルドする際に自動的に利用可能になります。これは、Go言語が初期段階からコード品質とパフォーマンス分析を重視していたことを示しており、開発者がこれらのツールを容易に利用できる環境を整備する意図があります。
  2. コンパイラ警告のクリーンアップ:

    • 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言語の公式ドキュメント
  • C言語の型とビット演算に関する一般的な知識
  • C言語のコンパイラ警告と抑制に関する一般的な慣習
  • Gitのコミット履歴と差分表示の分析