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

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

コミット

cmd/gc: Plan 9 上での警告を修正

このコミットは、Goコンパイラのgcコマンドにおいて、Plan 9オペレーティングシステム上で発生していたフォーマットミスマッチの警告を修正するものです。具体的には、src/cmd/gc/popt.cファイルの700行目で発生していたformat mismatch d VLONGという警告に対処しています。

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

https://github.com/golang/go/commit/a3e3b8e9db553fb6870c9488e9817f4bd0bb9593

元コミット内容

commit a3e3b8e9db553fb6870c9488e9817f4bd0bb9593
Author: David du Colombier <0intro@gmail.com>
Date:   Thu Feb 13 07:28:22 2014 +0100

    cmd/gc: fix warnings on Plan 9
    
    warning: src/cmd/gc/popt.c:700 format mismatch d VLONG, arg 4
    warning: src/cmd/gc/popt.c:700 format mismatch d VLONG, arg 5
    
    LGTM=rsc
    R=rsc
    CC=golang-codereviews
    https://golang.org/cl/62910043

変更の背景

このコミットは、GoコンパイラのgcがPlan 9上でビルドまたは実行された際に発生する警告を解消するために行われました。警告メッセージ「format mismatch d VLONG」は、printfのようなフォーマット出力関数において、期待される引数の型と実際に渡された引数の型が一致しないことを示しています。特にd VLONGという記述は、long long型の整数を%d(通常はint型用)で出力しようとした際に発生する可能性が高いです。

Plan 9は、ベル研究所で開発された分散オペレーティングシステムであり、Go言語の開発者の一部がその設計思想に影響を受けていることでも知られています。Goコンパイラは様々なプラットフォームをサポートしており、その中にはPlan 9も含まれています。このようなプラットフォーム固有の警告は、コンパイラのビルドプロセスをクリーンに保ち、潜在的なバグや未定義の動作を防ぐ上で重要です。

前提知識の解説

  • Goコンパイラ (gc): Go言語の公式コンパイラです。Goのソースコードを機械語に変換する役割を担います。cmd/gcは、そのコンパイラのコマンドラインツール部分を指します。
  • Plan 9 from Bell Labs: ベル研究所で開発された分散オペレーティングシステムです。UNIXの後継として設計され、ネットワーク透過性やファイルシステム中心の設計が特徴です。Go言語の設計思想、特に並行処理やモジュール性において、Plan 9の影響が見られます。
  • フォーマット文字列と型ミスマッチ: C言語やGo言語のfmtパッケージ(内部的にはCのprintfに似たメカニズムを使用)のようなフォーマット出力関数では、出力するデータの型に合わせて適切なフォーマット指定子(例: %d%s%f)を使用する必要があります。
    • %d: 通常、int型の整数を出力するために使用されます。
    • %lld (または %I64d など、コンパイラや環境による): long long型の整数を出力するために使用されます。
    • VLONG: この文脈では、おそらくGoコンパイラの内部でlong long型に相当する、あるいはそれよりも大きいサイズの整数型を指すカスタムの型定義または概念であると考えられます。C言語のlong long型は、少なくとも64ビットの幅を持つことが保証されています。
  • 警告 (Warning): プログラムのコンパイル時にコンパイラが発行するメッセージで、プログラムの動作には直接影響しないものの、潜在的な問題や非推奨の構文、または移植性の問題を示唆するものです。今回のケースでは、フォーマットミスマッチが未定義の動作を引き起こす可能性があったり、異なる環境での挙動の違いにつながる可能性があったため、警告として報告されました。

技術的詳細

この修正は、src/cmd/gc/popt.cファイル内のmergetemp関数におけるprint文のフォーマット指定子を変更することで行われています。

元のコードでは、v->startv->endという変数を%dというフォーマット指定子で出力しようとしていました。警告メッセージから、これらの変数がVLONG、すなわちlong long型に相当する、またはそれよりも大きいサイズの整数型であったことが示唆されます。

Plan 9のCコンパイラ(またはそのランタイムライブラリ)が、long long型の引数に対して%dを使用した場合に警告を発するように設定されていたため、このミスマッチが検出されました。一般的なC言語の規約では、long long型には%lldを使用するのが正しいとされています。

このコミットでは、%d%lldに変更することで、v->startv->endの実際の型(long long型に相当)とフォーマット指定子を一致させ、警告を解消しています。これにより、コンパイラのビルドプロセスがクリーンになり、将来的な潜在的な問題が回避されます。

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

--- a/src/cmd/gc/popt.c
+++ b/src/cmd/gc/popt.c
@@ -697,7 +697,7 @@ mergetemp(Prog *firstp)
 	if(Debug) {
 		print("%S [%d - %d]\n", curfn->nname->sym, nvar, nkill);
 		for(v=var; v<var+nvar; v++) {
-			print("var %#N %T %d-%d", v->node, v->node->type, v->start, v->end);
+			print("var %#N %T %lld-%lld", v->node, v->node->type, v->start, v->end);
 			if(v->addr)
 				print(" addr=1");
 			if(v->removed)

コアとなるコードの解説

変更はsrc/cmd/gc/popt.cファイルのmergetemp関数内で行われています。

  • 変更前:
    print("var %#N %T %d-%d", v->node, v->node->type, v->start, v->end);
    
    ここでは、v->startv->endという変数を%dというフォーマット指定子で出力しようとしていました。
  • 変更後:
    print("var %#N %T %lld-%lld", v->node, v->node->type, v->start, v->end);
    
    %d%lldに変更されています。この変更により、v->startv->endlong long型(またはそれに相当する型)であると仮定され、その型に合わせた正しいフォーマット指定子が使用されるようになりました。これにより、Plan 9環境でのコンパイル時の警告が解消されます。

このprint文は、デバッグ目的で変数の情報(名前、型、開始位置、終了位置など)を出力するために使用されていたと考えられます。v->startv->endは、おそらくコンパイラの内部で変数の生存期間やメモリ上の位置を示すオフセットなどを表す値であり、その値がint型では収まらない、またはlong long型として扱われるべきであったため、この修正が必要となりました。

関連リンク

参考にした情報源リンク

  • Go言語のソースコード (特にsrc/cmd/gcディレクトリ)
  • C言語のprintfフォーマット指定子に関する一般的なドキュメント
  • Plan 9オペレーティングシステムに関する情報