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

[インデックス 11678] ファイルの概要

このコミットは、Go言語のリポジトリにおいて、test/fixedbugs/bug408.go というテストファイルを削除するものです。このテストは、cgo を使用した際に発生する特定のエラー(printf(nil) の呼び出しにおける型不一致エラー)を検出することを目的としていましたが、再現性がなくなり、無効化されていたため削除されました。

コミット

commit c5de9b773faa7cfa843f94a1e24866c78353e386
Author: Rob Pike <r@golang.org>
Date:   Wed Feb 8 10:52:54 2012 +1100

    bug408: delete
    It's disabled and unreproducible.
    
    R=golang-dev, bradfitz
    CC=golang-dev
    https://golang.org/cl/5642053
---
 test/fixedbugs/bug408.go | 20 --------------------
 1 file changed, 20 deletions(-)

diff --git a/test/fixedbugs/bug408.go b/test/fixedbugs/bug408.go
deleted file mode 100644
index 65e5497ed0..0000000000
--- a/test/fixedbugs/bug408.go
+++ /dev/null
@@ -1,20 +0,0 @@
-// true
-
-// WAS: errchk cgo $D/$F.go
-// but this fails (cgo succeeds) on OS X Snow Leopard
-// with Xcode 4.2 and gcc version 4.2.1 (Based on Apple Inc. build 5658) (LLVM build 2336.1.00).\n-\n-// Copyright 2012 The Go Authors.  All rights reserved.\n-// Use of this source code is governed by a BSD-style\n-// license that can be found in the LICENSE file.\n-\n-// Issue 1800: cgo not reporting line numbers.\n-\n-package main\n-\n-// #include <stdio.h>\n-import \"C\"\n-\n-func f() {\n-\tC.printf(nil) // ERROR \"go:15.*unexpected type\"\n-}\n```

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

[https://github.com/golang/go/commit/c5de9b773faa7cfa843f94a1e24866c78353e386](https://github.com/golang/go/commit/c5de9b773faa7cfa843f94a1e24866c78353e386)

## 元コミット内容

削除された `test/fixedbugs/bug408.go` ファイルは、`cgo` を使用したGoプログラムのテストケースでした。このテストの目的は、C言語の `printf` 関数をGoから呼び出す際に、誤った型の引数(この場合は `nil`)を渡した場合に `cgo` が適切なエラーメッセージを報告するかどうかを検証することでした。具体的には、`C.printf(nil)` という呼び出しが `go:15.*unexpected type` というエラーを発生させることを期待していました。

このテストファイルには、元々 `errchk cgo $D/$F.go` というコメントがあり、これは `cgo` コマンドでコンパイルし、特定のエラー出力をチェックするテストであることを示しています。しかし、コメントには「OS X Snow Leopard の Xcode 4.2 および gcc version 4.2.1 (LLVM build 2336.1.00) では、cgo が成功し、このテストが失敗する」という記述があり、特定の環境で期待通りのエラーが発生しない問題が示唆されていました。

また、ファイル内には `// Issue 1800: cgo not reporting line numbers.` というコメントも含まれており、これは `cgo` がエラー発生時に正しい行番号を報告しないという、より広範な問題(Go Issue 1800)に関連していることを示しています。

## 変更の背景

このコミットの背景には、`test/fixedbugs/bug408.go` テストが「無効化されており、再現不可能である」という事実があります。

元のテストは、`cgo` が `C.printf(nil)` のような不正なC関数呼び出しに対して、コンパイル時に `unexpected type` エラーを適切に報告するかどうかを検証するものでした。しかし、コミットメッセージによると、このテストはもはや再現性がなく、期待されるエラーが発生しなくなっていたようです。テストが再現不可能であるということは、そのテストがもはやGoコンパイラや `cgo` ツールの現在の動作を正確に反映していないか、またはテストが意図したバグが既に修正されていることを意味します。

また、テストファイル内のコメント `// WAS: errchk cgo $D/$F.go // but this fails (cgo succeeds) on OS X Snow Leopard` は、特定の環境(OS X Snow Leopard)で既にこのテストが失敗していたことを示しています。これは、`cgo` の動作がプラットフォームやコンパイラのバージョンによって異なる可能性を示唆しており、テストの信頼性を低下させる要因となります。

さらに、`// Issue 1800: cgo not reporting line numbers.` というコメントは、このテストが `cgo` のエラーメッセージにおける行番号の報告に関する一般的な問題(Go Issue 1800)に関連していたことを示唆しています。Go Issue 1800は、`cmd/cgo` ツールが「unexpected type」メッセージに対して行番号を欠落させるという長年の問題であり、2016年には「FrozenDueToAge」(古すぎて凍結)とマークされるほど、長期間未解決の状態でした。

テストが再現不可能で無効化されている場合、それをリポジトリに残しておくことは、ビルド時間の増加、誤解を招く可能性、およびメンテナンスの負担につながります。そのため、このテストを削除することが決定されました。

## 前提知識の解説

### Go言語の `cgo`

`cgo` はGo言語のツールの一つで、GoプログラムからC言語のコードを呼び出したり、C言語のコードからGoの関数を呼び出したりするためのメカニズムを提供します。これにより、既存のCライブラリをGoプロジェクトで再利用したり、パフォーマンスが重要な部分をCで記述したりすることが可能になります。

`cgo` を使用するには、Goのソースファイル内に `import "C"` という特別なインポート文を記述し、その直前のコメントブロックにC言語のコードを記述します。このCコードは、Goプログラムから `C.関数名` の形式で呼び出すことができます。

### `printf` 関数

`printf` はC言語の標準ライブラリ `stdio.h` で定義されている関数で、書式指定文字列とそれに続く引数に基づいて標準出力にテキストを出力するために使用されます。非常に汎用的な関数であり、デバッグや情報表示によく用いられます。

### エラーメッセージにおける行番号

プログラミングにおいて、コンパイラやインタプリタがエラーを報告する際、エラーが発生したファイル名と行番号を示すことは非常に重要です。これにより、開発者は問題の箇所を迅速に特定し、デバッグすることができます。行番号が欠落していると、エラーの原因を特定する作業が著しく困難になります。

### `errchk` ディレクティブ

Goのテストフレームワークには、特定のテストファイルがコンパイル時に特定のエラーを発生させることを期待する場合に、そのエラーメッセージをチェックするための特別なディレクティブが存在します。`// errchk` はその一つで、テストの実行時にコンパイラの出力が期待されるエラーメッセージと一致するかどうかを検証します。これにより、コンパイラが特定の不正なコードに対して正しくエラーを報告するかどうかをテストできます。

## 技術的詳細

削除された `test/fixedbugs/bug408.go` ファイルは、`cgo` のエラー報告メカニズムをテストするためのものでした。

```go
// true

// WAS: errchk cgo $D/$F.go
// but this fails (cgo succeeds) on OS X Snow Leopard
// with Xcode 4.2 and gcc version 4.2.1 (Based on Apple Inc. build 5658) (LLVM build 2336.1.00).

// Copyright 2012 The Go Authors.  All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Issue 1800: cgo not reporting line numbers.

package main

// #include <stdio.h>
import "C"

func f() {
	C.printf(nil) // ERROR "go:15.*unexpected type"
}

このコードの核心は C.printf(nil) の行です。C言語の printf 関数は、第一引数に const char * 型の書式指定文字列を期待します。しかし、Goの nil はポインタ型やインターフェース型など、様々な型のゼロ値を表すことができますが、Cの const char * に直接変換できるわけではありません。特に、printfNULL ポインタを渡すことは未定義動作を引き起こす可能性があり、コンパイラは通常、型不一致としてこれを検出します。

このテストは、cgo がこの型不一致を検出し、go:15.*unexpected type というエラーメッセージを、ファイル名と行番号(この場合は15行目)を含めて出力することを期待していました。ERROR "..." コメントは、Goのテストシステムがこの行で指定された正規表現に一致するエラーメッセージを期待することを示す errchk ディレクティブの一部です。

しかし、コメントにあるように、OS X Snow Leopard の特定のXcodeおよびGCCバージョンでは cgo が成功し、期待されるエラーが発生しなかったようです。これは、cgo の内部的な型チェックロジックがプラットフォームやCコンパイラのバージョンによって異なる挙動を示していた可能性を示唆しています。

時間が経過するにつれて、Goのツールチェインや cgo の実装が進化し、この特定のバグ(またはその再現条件)が変化した可能性があります。その結果、このテストはもはや期待されるエラーを再現できなくなり、「無効化され、再現不可能」と判断されたため、削除されることになりました。

Go Issue 1800 は、cgo がエラーメッセージに行番号を報告しないという、より一般的な問題に焦点を当てていました。このテストは、その問題の具体的なケースを捉えようとしたものですが、テスト自体の再現性の問題により、その目的を果たすことができなくなっていました。

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

このコミットにおけるコアとなるコードの変更箇所は、以下のファイルの削除です。

  • test/fixedbugs/bug408.go

このファイルは完全に削除され、変更行数は20行の削除(20 --------------------)となっています。

コアとなるコードの解説

test/fixedbugs/bug408.go ファイルの削除は、Go言語のテストスイートから、もはや有効ではない、または再現不可能なテストケースが取り除かれたことを意味します。

Goプロジェクトでは、test/fixedbugs ディレクトリは、過去に発見され修正されたバグに対する回帰テストを格納するために使用されます。これらのテストは、将来的に同じバグが再発しないことを保証するために重要です。しかし、この bug408.go のケースでは、テストが特定の環境で既に失敗しており、最終的には「無効化され、再現不可能」と判断されました。

テストが再現不可能である場合、それは以下のいずれかの状況を示唆します。

  1. バグが修正された: 元々このテストが検出していたバグが、Goコンパイラや cgo の後のバージョンで修正されたため、エラーが発生しなくなった。
  2. 再現条件の変化: バグの再現条件が、Goのツールチェインや依存するCコンパイラの変更によって変化し、現在の環境では再現できなくなった。
  3. テストの不正確さ: テスト自体が、バグを正確に捉えるための条件を満たしていなかったか、または期待されるエラーメッセージが環境に依存しすぎていた。

いずれの場合も、再現不可能なテストを維持することは、テストスイートの健全性を損ないます。無効なテストは、開発者がテスト結果を信頼するのを妨げ、ビルド時間を不必要に増加させ、メンテナンスの負担となります。したがって、このテストを削除することは、テストスイートをクリーンに保ち、より信頼性の高いものにするための合理的な決定です。

この削除は、Go Issue 1800(cgo が行番号を報告しない問題)が、この特定のテストケースではもはや追跡できない、またはこのテストケースがその問題の適切な再現方法ではなかったことを間接的に示している可能性もあります。

関連リンク

参考にした情報源リンク