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

[インデックス 109] Go言語初期開発におけるテストケース追加 - 再宣言エラーとインターフェース構文の検証

コミット

コミットハッシュ: 5182aff001488a791747439f33d6d92d076ebd7a
作成者: Robert Griesemer gri@golang.org
日付: 2008年6月6日(金)16:59:54 -0700
SVN リビジョン: 121546

コミットメッセージ: "- more tests (mostly redeclaration errors that are not checked)"

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

https://github.com/golang/go/commit/5182aff001488a791747439f33d6d92d076ebd7a

元コミット内容

このコミットは、Go言語の初期開発段階において、9個の新しいテストケースファイル(bug032.go〜bug040.go)を追加し、テストの期待結果を示すgolden.outファイルを更新したものです。これらのテストケースは、主に以下の領域での不適切な動作を検証するものです:

  • インターフェース構文エラー: 複数メソッド名の同時宣言、func キーワードの誤用
  • 再宣言エラー: 変数名の重複、関数パラメータの重複
  • 型システムエラー: 未定義型(vlong)の使用

変更の背景

2008年の時点でGo言語は、Robert Griesemer、Rob Pike、Ken Thompsonによって開発されており、まだ言語仕様や実装が固まっていない実験的な段階にありました。このコミットは、Go言語コンパイラの品質向上のため、エラー検出機能の網羅的テストを追加するものです。

特に、このコミットは以下の問題に対処しています:

  1. 未検出の再宣言エラー: コンパイラがチェックすべき再宣言エラーを適切に検出できていない
  2. インターフェース構文の検証不足: 不正なインターフェース定義を受け入れてしまう問題
  3. 型システムの堅牢性: 未定義型に対する適切なエラーハンドリング

前提知識の解説

Go言語の開発タイムライン(2007-2008年)

Go言語の開発は2007年9月21日にRobert Griesemer、Rob Pike、Ken Thompsonがホワイトボードに新しい言語のゴールを描いたことから始まりました。2008年1月には、Ken ThompsonがC言語を出力するコンパイラの開発を開始し、2008年中頃には本格的なプロジェクトへと発展しました。

SVN(Subversion)の使用

Go言語プロジェクトは当初SVNを使用しており、後にPerforce、Mercurial、最終的にGitへと移行しました。SVN=121546は、このコミットが行われた時点でのSubversionリビジョン番号です。

Go言語の再宣言ルール

Go言語では以下の再宣言ルールがあります:

  • 短い変数宣言(:=)では、同じブロック内で同じ型の変数を再宣言可能
  • ただし、少なくとも1つの新しい変数が必要
  • 関数パラメータでは同じ名前は使用不可
  • 戻り値の名前付きパラメータでは再宣言エラーが発生

インターフェース構文規則

Go言語のインターフェースでは:

  • メソッド名は1つずつ宣言する必要がある
  • funcキーワードはインターフェース内で使用禁止
  • 構造的型付け(structural typing)を採用

技術的詳細

追加されたテストケース

bug032.go: インターフェース内での複数メソッド名同時宣言エラー

type I interface {
    g,f    ()int;  // BUG only one method name allowed per signature
}

bug033.go & bug034.go: インターフェース内でのfuncキーワード使用エラー

type Iputs interface {
    puts func(s string);  // BUG no func allowed
}

bug035.go: 戻り値の名前付きパラメータ再宣言エラー

func f9(a int) (i int, f float) {
    i := 9;  // BUG redeclaration
    f := float(9);  // BUG redeclaration
    return i, f;
}

bug036.go: 同一変数の再宣言エラー

func main() {
    s := float(0);
    s := float(0);  // BUG redeclaration
}

bug037.go: 未定義型の使用エラー

func main() {
    s := vlong(0);  // BUG no vlong specified in the language
}

bug038.go: 配列変数の再宣言エラー

func main() {
    var z [3]byte;
    z := new([3]byte);  // BUG redeclaration
}

bug039.go: 関数パラメータと局所変数の名前衝突エラー

func main (x int) {
    var x int;  // BUG redeclaration error
}

bug040.go: 関数パラメータでの同名パラメータエラー

func main (x, x int) {  // BUG redeclaration error
}

テストシステムの構成

各テストファイルには以下の指示が含まれています:

  • // $G $F.go && echo BUG: compilation succeeds incorrectly: コンパイルが成功してしまう場合のテスト
  • // errchk $G $D/$F.go: エラーチェック機能のテスト
  • // ! $G $D/$F.go >/dev/null: コンパイルエラーを期待するテスト

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

1. インターフェース構文チェック(bug032.go)

type I interface {
    g,f    ()int;  // 複数メソッド名の同時宣言
}

この構文は、1つのシグネチャに対して複数のメソッド名を宣言しようとしているため、Go言語の構文規則に違反しています。

2. インターフェース内func使用チェック(bug033.go, bug034.go)

type Iputs interface {
    puts func(s string);  // func キーワードの不正使用
}

インターフェース内ではfuncキーワードは使用できません。正しくはputs(s string)と記述する必要があります。

3. 再宣言エラー検出(bug035.go〜bug040.go)

各テストは異なる種類の再宣言エラーを検証:

  • 戻り値パラメータの再宣言
  • 同一スコープ内での変数再宣言
  • 関数パラメータの重複
  • 変数宣言とnew()による再宣言

コアとなるコードの解説

テストの実行メカニズム

  1. コンパイル成功判定: $G $F.go && echo BUG: compilation succeeds incorrectly

    • コンパイラ($G)がファイル($F.go)をコンパイル
    • 成功した場合、バグとして報告
  2. エラーチェック: errchk $G $D/$F.go

    • エラーチェックツールによる検証
    • 期待されるエラーが発生するかを確認
  3. 期待される失敗: ! $G $D/$F.go >/dev/null

    • コンパイルが失敗することを期待
    • 出力は破棄(>/dev/null)

golden.outファイルの更新

テストの期待結果を記録するgolden.outファイルに、新しいテストケースの結果が追加されました:

=========== ./bug032.go
BUG: compilation succeeds incorrectly
...
=========== ./bug040.go
BUG: compilation succeeds incorrectly

これらの出力は、コンパイラが本来エラーを検出すべきコードを正常にコンパイルしてしまっているバグを示しています。

関連リンク

参考にした情報源リンク