[インデックス 1180] ファイルの概要
このコミットは、Go言語の初期のコンパイラ(6g
、64ビットシステム向けのGoコンパイラ)におけるGCCコンパイラの警告を解消するための変更です。具体的には、プロトタイプ宣言の不足と未使用変数の存在によって発生していた警告を抑制することを目的としています。
コミット
commit 9a6fd41a018c333f77d104e1d5ca97b97e508f8e
Author: Russ Cox <rsc@golang.org>
Date: Wed Nov 19 09:49:06 2008 -0800
silence gcc warnings: missing prototypes and unused variables
R=ken
OCL=19583
CL=19583
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/9a6fd41a018c333f77d104e1d5ca97b97e508f8e
元コミット内容
--- a/src/cmd/6g/gen.c
+++ b/src/cmd/6g/gen.c
@@ -6,6 +6,7 @@
#undef EXTERN
#define EXTERN
#include "gg.h"
+#include "opt.h"
enum
{
@@ -515,7 +516,7 @@ swgen(Node *n)
Case *s0, *se, *s, *sa;
Prog *p1, *dflt;
int32 lno;
- int any, nc, w;
+ int any, nc;
Iter save1, save2;
// botch - put most of this code in
diff --git a/src/cmd/6g/opt.h b/src/cmd/6g/opt.h
index f51cd75fcb..a73e45ffc7 100644
--- a/src/cmd/6g/opt.h
+++ b/src/cmd/6g/opt.h
@@ -149,6 +149,7 @@ Bits
blsh(uint);
int beq(Bits, Bits);
int bset(Bits, uint);
int Qconv(Fmt *fp);
+int bitno(int32);
/*
* reg.c
diff --git a/src/cmd/6g/reg.c b/src/cmd/6g/reg.c
index 70b936ee7a..3e319919db 100644
--- a/src/cmd/6g/reg.c
+++ b/src/cmd/6g/reg.c
@@ -36,7 +36,7 @@
#define P2R(p) (Reg*)(p->reg)
#define MAGIC 0xb00fbabe
-static first = 1;
+static int first = 1;
static void dumpit(char *str, Reg *r0);\n static int noreturn(Prog *p);
@@ -73,8 +73,8 @@ rcmp(const void *a1, const void *a2)
void
regopt(Prog *firstp)
{
-\tReg *r, *r1, *r2;\n-\tProg *p1, *p;
+\tReg *r, *r1;
+\tProg *p;
int i, z, nr;
uint32 vreg;
Bits bit;
変更の背景
このコミットは、Go言語の初期のコンパイラである6g
(Plan 9スタイルのコンパイラ群の一部で、64ビットアーキテクチャ向けのGoコンパイラ)が、GCC(GNU Compiler Collection)でコンパイルされる際に発生していた警告を解消するために行われました。当時のGoコンパイラはC言語で書かれており、GCCでビルドされていました。
警告は主に以下の2つのカテゴリに分類されます。
- プロトタイプ宣言の不足 (missing prototypes): 関数が使用される前にその宣言(プロトタイプ)がない場合に発生する警告です。C言語では、関数が呼び出される前にそのシグネチャ(戻り値の型、引数の型と数)がコンパイラに知らされていないと、コンパイラは関数の呼び出し規約や型チェックを正しく行えず、潜在的なバグや未定義動作につながる可能性があります。
- 未使用変数 (unused variables): 変数が宣言されたものの、コード内で一度も使用されていない場合に発生する警告です。これは、コードのデッドコード(到達不能コード)や、意図しない変数宣言、あるいは単なるタイポなどを示すことがあり、コードの品質や保守性を低下させる可能性があります。
これらの警告は、コンパイラのビルドプロセスをクリーンに保ち、将来的なエラーの可能性を減らすために重要です。警告がない状態は、開発者が本当に重要なエラーメッセージに集中できる環境を提供します。
前提知識の解説
- Go言語の初期コンパイラ (
6g
,8g
,5g
など): Go言語の初期バージョンでは、現在のGoコンパイラ(go tool compile
)とは異なり、Plan 9オペレーティングシステムのツールチェインにインスパイアされたC言語で書かれたコンパイラが使用されていました。6g
はAMD64(x86-64)アーキテクチャ向けのGoコンパイラを指します。同様に8g
は386(x86)向け、5g
はARM向けでした。これらはGoのソースコードをアセンブリコードに変換する役割を担っていました。 - GCC (GNU Compiler Collection): C、C++、Objective-C、Fortran、Ada、Goなど、多くのプログラミング言語をサポートするフリーのコンパイラシステムです。Linuxシステムなどで広く利用されており、Go言語の初期コンパイラもGCCを使ってビルドされていました。
- コンパイラの警告 (Compiler Warnings): コンパイラがソースコードを解析する際に、プログラムの実行には影響しないものの、潜在的な問題や非推奨の構文、あるいはプログラミング上の誤りを示唆するメッセージです。警告はエラーとは異なり、プログラムのコンパイル自体は成功しますが、無視すると将来的にバグにつながる可能性があります。
- プロトタイプ宣言 (Function Prototypes): C言語において、関数が定義される前にその関数のシグネチャ(戻り値の型、関数名、引数の型と数)を宣言することです。これにより、コンパイラは関数が呼び出される際に正しい引数の型チェックや戻り値の処理を行うことができます。通常、ヘッダーファイル(
.h
)に記述されます。 - 未使用変数 (Unused Variables): プログラム内で宣言されたにもかかわらず、その値が一度も読み取られたり、変更されたりしない変数のことです。これは、コードの冗長性や、論理的な誤りを示す可能性があります。
技術的詳細
このコミットで行われた変更は、GCCの警告を抑制するための典型的なC言語のコーディングプラクティスに沿っています。
-
src/cmd/6g/gen.c
におけるopt.h
のインクルード:gen.c
内でbitno
関数が使用されていたにもかかわらず、そのプロトタイプ宣言がコンパイラに認識されていなかったことが原因で「missing prototype」警告が発生していました。bitno
関数のプロトタイプはopt.h
に定義されています。gen.c
に#include "opt.h"
を追加することで、bitno
関数のプロトタイプがコンパイル時に利用可能になり、警告が解消されます。- これは、C言語におけるヘッダーファイルの役割(関数や変数の宣言を提供し、複数のソースファイル間で共有可能にする)を適切に利用した修正です。
-
src/cmd/6g/gen.c
における未使用変数w
の削除:swgen
関数内でint w;
と宣言されていた変数w
が、コード内で一度も使用されていませんでした。- 未使用変数はコンパイラ警告の一般的な原因であり、単に宣言を削除することで警告を解消できます。これはコードの冗長性を減らし、可読性を向上させる効果もあります。
-
src/cmd/6g/opt.h
におけるbitno
関数のプロトタイプ追加:int bitno(int32);
というプロトタイプがopt.h
に追加されました。これは、gen.c
でbitno
関数が使用される前にその宣言が利用可能になるようにするためのものです。- この変更は、
gen.c
での#include "opt.h"
の追加と合わせて、bitno
関数の「missing prototype」警告を完全に解消します。
-
src/cmd/6g/reg.c
におけるstatic first = 1;
からstatic int first = 1;
への変更:- C言語では、変数を宣言する際に型を省略すると、デフォルトで
int
型とみなされることがありますが、これは古いCの慣習であり、現代のC言語では明示的に型を指定することが推奨されます。 static first = 1;
という宣言は、コンパイラによっては警告(例えば「type defaults to 'int' in declaration」など)を出す可能性があります。static int first = 1;
と明示的にint
型を指定することで、この種の警告を抑制し、コードの明確性を向上させます。
- C言語では、変数を宣言する際に型を省略すると、デフォルトで
-
src/cmd/6g/reg.c
における未使用変数r2
とp1
の削除:regopt
関数内でReg *r2;
とProg *p1;
が宣言されていましたが、これらがコード内で使用されていませんでした。gen.c
のw
と同様に、これらの未使用変数を削除することで、コンパイラ警告を解消し、コードをクリーンに保ちます。
これらの変更は、コードの機能には影響を与えず、コンパイラの警告を解消し、ビルドプロセスをよりスムーズにするためのコード品質向上を目的としたものです。
コアとなるコードの変更箇所
src/cmd/6g/gen.c
:#include "opt.h"
の追加。swgen
関数内の変数宣言からw
を削除。
src/cmd/6g/opt.h
:int bitno(int32);
のプロトタイプ宣言を追加。
src/cmd/6g/reg.c
:static first = 1;
をstatic int first = 1;
に変更。regopt
関数内の変数宣言からr2
とp1
を削除。
コアとなるコードの解説
-
src/cmd/6g/gen.c
の変更:#include "opt.h"
: この行は、gen.c
がopt.h
で定義されている関数やマクロを使用できるようにするために追加されました。特に、bitno
関数のプロトタイプがopt.h
に存在するため、このインクルードによってgen.c
内でbitno
が呼び出される際の「missing prototype」警告が解消されます。int any, nc, w;
からint any, nc;
へ:swgen
関数内でw
という変数が宣言されていましたが、その後のコードで一度も使用されていませんでした。この変更は、未使用変数の警告を解消するために、単にw
の宣言を削除したものです。
-
src/cmd/6g/opt.h
の変更:int bitno(int32);
: この行は、bitno
という名前の関数が、int32
型の引数を一つ取り、int
型の値を返すことを宣言しています。このプロトタイプ宣言がopt.h
に追加されたことで、gen.c
のような他のソースファイルがopt.h
をインクルードする際に、bitno
関数の存在とシグネチャを事前に知ることができ、コンパイラが警告を発しなくなります。
-
src/cmd/6g/reg.c
の変更:static first = 1;
からstatic int first = 1;
へ:first
という静的変数が初期値1
で宣言されていましたが、型が明示されていませんでした。C言語の古い慣習では型を省略するとint
とみなされることがありますが、現代のコンパイラでは警告の対象となることがあります。int
を明示的に追加することで、この警告を解消し、コードの意図を明確にしています。Reg *r, *r1, *r2;
からReg *r, *r1;
へ:regopt
関数内でr2
というReg
型のポインタ変数が宣言されていましたが、コード内で使用されていませんでした。Prog *p1, *p;
からProg *p;
へ: 同様に、p1
というProg
型のポインタ変数が宣言されていましたが、使用されていませんでした。- これらの変更は、未使用変数の警告を解消するために、
r2
とp1
の宣言を削除したものです。
関連リンク
- Go言語の初期コンパイラに関する情報: https://go.dev/doc/install/source (Goのソースからのビルドに関する公式ドキュメント、初期のコンパイラについても言及がある場合があります)
- Plan 9 from Bell Labs: https://9p.io/plan9/ (Goの初期コンパイラが影響を受けたPlan 9オペレーティングシステムに関する情報)
参考にした情報源リンク
- GCC Compiler Warnings: https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html
- C Language Function Prototypes: https://www.geeksforgeeks.org/function-prototype-in-c/
- Unused Variables in C: https://stackoverflow.com/questions/1000000/what-is-an-unused-variable-warning-and-how-do-i-fix-it
- Go's Original Compiler: https://go.dev/blog/go-compiler-internals (Goコンパイラの内部に関するブログ記事、初期のコンパイラについても触れられている可能性があります)
- Go's Toolchain: https://go.dev/doc/go1.4 (Go 1.4のリリースノート、Goコンパイラのセルフホスト化に関する重要な情報が含まれています)
- Go's History: https://go.dev/doc/history (Go言語の歴史に関する公式ドキュメント)