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

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

このコミットは、Go言語のツールチェインの一部である gopack コマンドに関連する src/cmd/gopack/ar.c ファイルに対する変更です。gopack は、Goのパッケージアーカイブ(.a ファイル)を作成・管理するためのユーティリティであり、ar.c はその中でUnixの ar (archiver) コマンドと同様のアーカイブ操作、特にアーカイブメンバーのヘッダ情報の処理を担当しています。このファイルはC言語で書かれており、Goの初期のツールチェインがC言語で実装されていた名残を示しています。

コミット

このコミットは、gopack ツールがPlan 9オペレーティングシステム上で正しくビルドされるようにするための修正と、ビルドの冪等性(idempotency)を向上させるための変更を含んでいます。具体的には、不要な初期化の削除と、sprint 関数での数値リテラル 00L (long型) に変更することで、フォーマット指定子 %ld との型の一致を図っています。

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

https://github.com/golang/go/commit/74f61fc656fdcd7ded63660c542b0820202120db

元コミット内容

gopack: fixes for Plan 9 build

. removed an unnexessary initialisation.
. replaced 0 with 0L to match print format that in turn matched
  the type of the original function return value.

R=golang-dev
CC=golang-dev, rsc
https://golang.org/cl/5306072

変更の背景

この変更は主に二つの目的を持っています。

  1. Plan 9ビルドの修正: Go言語は、その設計思想や初期開発においてPlan 9オペレーティングシステムの影響を強く受けています。Goのツールチェインは、Plan 9環境でもビルドおよび実行できることが重要視されていました。このコミットは、gopack がPlan 9環境でコンパイルエラーを起こしたり、予期せぬ動作をしたりする問題を解決するために行われました。C言語のコードにおける型の一致や、特定の環境での挙動の違いが問題となっていた可能性があります。
  2. 冪等なビルドの実現: 「idempotent builds」(冪等なビルド)とは、同じソースコードとビルド環境であれば、何度ビルドしても全く同じバイナリ(またはアーカイブ)が生成されることを指します。これは、再現性のあるビルド、キャッシュの効率化、およびセキュリティの観点から非常に重要です。以前のコードでは、アーカイブのヘッダにタイムスタンプ(d->mtimetime(0))が書き込まれており、これによりビルドごとにアーカイブの内容が変化していました。このコミットでは、タイムスタンプの代わりに固定値 0 を書き込むことで、ビルドの冪等性を高めています。これにより、同じソースからビルドされたアーカイブは常に同じハッシュ値を持つようになり、ビルドの信頼性が向上します。

前提知識の解説

  • gopack: Go言語の初期のツールチェインの一部で、Goのパッケージアーカイブ(.a ファイル)を操作するためのコマンドラインツールです。Goのコンパイラが生成したオブジェクトファイルをまとめてライブラリを作成する際に使用されました。現代のGoでは、go buildgo install コマンドがこれらのアーカイブ操作を内部的に処理するため、gopack を直接使用することは稀です。
  • ar (archiver): Unix系システムで広く使われているアーカイブユーティリティです。複数のファイルを一つのアーカイブファイル(通常は .a 拡張子)にまとめるために使用されます。主に静的ライブラリ(.a ファイル)の作成に用いられます。gopackar.c ファイルは、この ar フォーマットのアーカイブを扱うためのC言語実装です。
  • Plan 9: ベル研究所で開発された分散オペレーティングシステムです。Go言語の設計者の一部(Ken Thompson, Rob Pike)はPlan 9の開発にも深く関わっており、Go言語の設計思想にはPlan 9の哲学が色濃く反映されています。Goの初期のツールチェインはPlan 9のツールチェインに影響を受けており、Plan 9上でのビルドもサポートされていました。
  • 冪等性 (Idempotency): ある操作を複数回実行しても、結果が常に同じになる性質を指します。ソフトウェア開発においては、ビルドプロセスやデプロイプロセスにおいて冪等性が確保されていると、予期せぬ副作用なしに何度でも同じ操作を繰り返すことができるため、信頼性と再現性が向上します。
  • sprint 関数: C言語の標準ライブラリ関数 sprintf のPlan 9版または類似の関数であると考えられます。sprintf は、指定されたフォーマットに従ってデータを文字列に整形し、バッファに書き込む関数です。
    • %-12ld: sprint 関数のフォーマット指定子です。
      • -: 左詰め
      • 12: 最小フィールド幅12文字
      • l: long 型の引数に対応
      • d: 符号付き10進整数として出力
    • このフォーマット指定子は long 型の引数を期待しているため、int 型の 0 ではなく long 型の 0L を渡すことで、型の一致を図り、潜在的な警告や未定義動作を避けることができます。
  • 0L: C言語における long 型の数値リテラルです。単なる 0 は通常 int 型として扱われますが、0L とすることで明示的に long 型であることを示します。

技術的詳細

このコミットで行われた技術的な変更は以下の通りです。

  1. time.h のインクルード削除:

    • src/cmd/gopack/ar.c から #include <time.h> が削除されました。
    • これは、以前のコードでアーカイブのヘッダにタイムスタンプを書き込むために time(0) 関数が使用されており、そのために time.h が必要だったためです。冪等なビルドのためにタイムスタンプの書き込みが不要になったため、関連するヘッダファイルも不要となり削除されました。これにより、コードの依存関係が減少し、クリーンアップが図られています。
  2. pkg = nil; の初期化削除:

    • foundstart: ラベルの後のコードブロックから pkg = nil; の行が削除されました。
    • コミットメッセージには「unnexessary initialisation」(不要な初期化)と記載されており、この pkg 変数の初期化がコードのロジック上、もはや必要ないか、あるいは別の場所で適切に初期化されるようになったため削除されたと考えられます。これにより、デッドコードの削除とコードの簡素化が実現されています。
  3. 0 から 0L への変更:

    • armove 関数と rl 関数内の複数の sprint 関数呼び出しにおいて、%-12ld フォーマット指定子で出力される値が 0 から 0L に変更されました。
    • 具体的には、bp->hdr.date (アーカイブメンバーの日付フィールド) や a.date (アーカイブヘッダの日付フィールド) に値を書き込む際に、以前は d->mtimetime(0) といったタイムスタンプが使用されていましたが、冪等なビルドのためにこれらが 0 に置き換えられました。
    • %-12ld というフォーマット指定子は long 型の引数を期待します。C言語では、0 はデフォルトで int 型として扱われるため、long 型を期待するフォーマット指定子に int 型の値を渡すと、コンパイラの警告や、場合によっては未定義動作を引き起こす可能性があります。0L と明示的に long 型のリテラルを使用することで、この型不一致の問題を解消し、コードの堅牢性を高めています。

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

--- a/src/cmd/gopack/ar.c
+++ b/src/cmd/gopack/ar.c
@@ -37,7 +37,6 @@
 #define rcmd your_rcmd
 
 #include <u.h>
-#include <time.h>
 #include <libc.h>
 #include <bio.h>
 #include <mach.h>
@@ -838,7 +837,6 @@ foundstart:
 		goto bad;
 
 	/* how big is it? */
-\tpkg = nil;
 	first = 1;
 	start = end = 0;
 	for (n=0; n<size; n+=Blinelen(b)) {
@@ -1102,7 +1100,7 @@ armove(Biobuf *b, Arfile *ap, Armember *bp)
 	for (cp = strchr(bp->hdr.name, 0);		/* blank pad on right */
 	cp < bp->hdr.name+sizeof(bp->hdr.name); cp++)
 			*cp = ' ';
-\tsprint(bp->hdr.date, "%-12ld", 0);  // was d->mtime but removed for idempotent builds
+\tsprint(bp->hdr.date, "%-12ld", 0L);  // was d->mtime but removed for idempotent builds
 	sprint(bp->hdr.uid, "%-6d", 0);
 	sprint(bp->hdr.gid, "%-6d", 0);
 	sprint(bp->hdr.mode, "%-8lo", d->mode);
@@ -1236,7 +1234,7 @@ rl(int fd)
 	len = symdefsize;
 	if(len&01)
 		len++;
-\tsprint(a.date, "%-12ld", 0);  // time(0)
+\tsprint(a.date, "%-12ld", 0L);  // time(0)
 	sprint(a.uid, "%-6d", 0);
 	sprint(a.gid, "%-6d", 0);
 	sprint(a.mode, "%-8lo", 0644L);
@@ -1273,7 +1271,7 @@ rl(int fd)
 
 	if (gflag) {
 		len = pkgdefsize;
-\tsprint(a.date, "%-12ld", 0);  // time(0)
+\tsprint(a.date, "%-12ld", 0L);  // time(0)
 		sprint(a.uid, "%-6d", 0);
 		sprint(a.gid, "%-6d", 0);
 		sprint(a.mode, "%-8lo", 0644L);

コアとなるコードの解説

  • - #include <time.h>:

    • この行の削除は、アーカイブのタイムスタンプを固定値 0 に変更したことによるものです。time.htime() 関数を提供し、システム時刻を取得するために使用されます。タイムスタンプが不要になったため、このヘッダファイルのインクルードも不要になりました。これにより、コンパイル時の依存関係が減少し、コードベースがよりスリムになります。
  • - pkg = nil;:

    • この行の削除は、pkg 変数の初期化が不要になったことを示しています。pkg はおそらく、アーカイブ内のパッケージ情報を扱うためのポインタ変数であり、以前はここで nil に初期化されていましたが、その後のコードロジックの変更により、この初期化が冗長になったか、別の場所でより適切な初期化が行われるようになったため削除されました。
  • - sprint(bp->hdr.date, "%-12ld", 0); から + sprint(bp->hdr.date, "%-12ld", 0L);:

    • この変更は、アーカイブメンバーのヘッダにある日付フィールド (bp->hdr.date) に値を書き込む部分です。
    • 以前は d->mtime (ファイルの最終更新時刻) が使用されていましたが、冪等なビルドのために 0 に変更されました。
    • %-12ld というフォーマット指定子は long 型の引数を期待します。0int 型として扱われるため、0L とすることで明示的に long 型のリテラルを渡し、型の一致を保証しています。これにより、コンパイラの警告を回避し、クロスプラットフォーム(特にPlan 9のような環境)での潜在的な問題を解消します。
  • - sprint(a.date, "%-12ld", 0); から + sprint(a.date, "%-12ld", 0L); (2箇所):

    • これらの変更は、アーカイブ全体のヘッダ (a.date) に値を書き込む部分です。
    • ここでも同様に、以前は time(0) (現在のシステム時刻) が使用されていましたが、冪等なビルドのために 0 に変更されました。
    • %-12ld フォーマット指定子との型の一致を保つため、00L に変更しています。これは、ビルドの再現性を高めると同時に、C言語の型システムにおけるベストプラクティスに従った修正です。

これらの変更は、Goのツールチェインが異なるオペレーティングシステム(特にPlan 9)でより堅牢に動作し、かつビルドの再現性(冪等性)を向上させるための重要なステップでした。

関連リンク

参考にした情報源リンク

  • (この解説の生成には、提供されたコミット情報と一般的なC言語、Unix ar、Go言語の知識、および冪等なビルドに関する概念が用いられています。特定の外部Webサイトへの参照は行っていません。)

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

このコミットは、Go言語のツールチェインの一部である gopack コマンドに関連する src/cmd/gopack/ar.c ファイルに対する変更です。gopack は、Goのパッケージアーカイブ(.a ファイル)を作成・管理するためのユーティリティであり、ar.c はその中でUnixの ar (archiver) コマンドと同様のアーカイブ操作、特にアーカイブメンバーのヘッダ情報の処理を担当しています。このファイルはC言語で書かれており、Goの初期のツールチェインがC言語で実装されていた名残を示しています。

コミット

このコミットは、gopack ツールがPlan 9オペレーティングシステム上で正しくビルドされるようにするための修正と、ビルドの冪等性(idempotency)を向上させるための変更を含んでいます。具体的には、不要な初期化の削除と、sprint 関数での数値リテラル 00L (long型) に変更することで、フォーマット指定子 %ld との型の一致を図っています。

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

https://github.com/golang/go/commit/74f61fc656fdcd7ded63660c542b0820202120db

元コミット内容

gopack: fixes for Plan 9 build

. removed an unnexessary initialisation.
. replaced 0 with 0L to match print format that in turn matched
  the type of the original function return value.

R=golang-dev
CC=golang-dev, rsc
https://golang.org/cl/5306072

変更の背景

この変更は主に二つの目的を持っています。

  1. Plan 9ビルドの修正: Go言語は、その設計思想や初期開発においてPlan 9オペレーティングシステムの影響を強く受けています。Goのツールチェインは、Plan 9環境でもビルドおよび実行できることが重要視されていました。このコミットは、gopack がPlan 9環境でコンパイルエラーを起こしたり、予期せぬ動作をしたりする問題を解決するために行われました。C言語のコードにおける型の一致や、特定の環境での挙動の違いが問題となっていた可能性があります。
  2. 冪等なビルドの実現: 「idempotent builds」(冪等なビルド)とは、同じソースコードとビルド環境であれば、何度ビルドしても全く同じバイナリ(またはアーカイブ)が生成されることを指します。これは、再現性のあるビルド、キャッシュの効率化、およびセキュリティの観点から非常に重要です。以前のコードでは、アーカイブのヘッダにタイムスタンプ(d->mtimetime(0))が書き込まれており、これによりビルドごとにアーカイブの内容が変化していました。このコミットでは、タイムスタンプの代わりに固定値 0 を書き込むことで、ビルドの冪等性を高めています。これにより、同じソースからビルドされたアーカイブは常に同じハッシュ値を持つようになり、ビルドの信頼性が向上します。

前提知識の解説

  • gopack: Go言語の初期のツールチェインの一部で、Goのパッケージアーカイブ(.a ファイル)を操作するためのコマンドラインツールです。Goのコンパイラが生成したオブジェクトファイルをまとめてライブラリを作成する際に使用されました。現代のGoでは、go buildgo install コマンドがこれらのアーカイブ操作を内部的に処理するため、gopack を直接使用することは稀です。
  • ar (archiver): Unix系システムで広く使われているアーカイブユーティリティです。複数のファイルを一つのアーカイブファイル(通常は .a 拡張子)にまとめるために使用されます。主に静的ライブラリ(.a ファイル)の作成に用いられます。gopackar.c ファイルは、この ar フォーマットのアーカイブを扱うためのC言語実装です。
  • Plan 9: ベル研究所で開発された分散オペレーティングシステムです。Go言語の設計者の一部(Ken Thompson, Rob Pike)はPlan 9の開発にも深く関わっており、Go言語の設計思想にはPlan 9の哲学が色濃く反映されています。Goの初期のツールチェインはPlan 9のツールチェインに影響を受けており、Plan 9上でのビルドもサポートされていました。
  • 冪等性 (Idempotency): ある操作を複数回実行しても、結果が常に同じになる性質を指します。ソフトウェア開発においては、ビルドプロセスやデプロイプロセスにおいて冪等性が確保されていると、予期せぬ副作用なしに何度でも同じ操作を繰り返すことができるため、信頼性と再現性が向上します。
  • sprint 関数: C言語の標準ライブラリ関数 sprintf のPlan 9版または類似の関数であると考えられます。sprintf は、指定されたフォーマットに従ってデータを文字列に整形し、バッファに書き込む関数です。
    • %-12ld: sprint 関数のフォーマット指定子です。
      • -: 左詰め
      • 12: 最小フィールド幅12文字
      • l: long 型の引数に対応
      • d: 符号付き10進整数として出力
    • このフォーマット指定子は long 型の引数を期待しているため、int 型の 0 ではなく long 型の 0L を渡すことで、型の一致を図り、潜在的な警告や未定義動作を避けることができます。
  • 0L: C言語における long 型の数値リテラルです。単なる 0 は通常 int 型として扱われますが、0L とすることで明示的に long 型であることを示します。

技術的詳細

このコミットで行われた技術的な変更は以下の通りです。

  1. time.h のインクルード削除:

    • src/cmd/gopack/ar.c から #include <time.h> が削除されました。
    • これは、以前のコードでアーカイブのヘッダにタイムスタンプを書き込むために time(0) 関数が使用されており、そのために time.h が必要だったためです。冪等なビルドのためにタイムスタンプの書き込みが不要になったため、関連するヘッダファイルも不要となり削除されました。これにより、コードの依存関係が減少し、クリーンアップが図られています。
  2. pkg = nil; の初期化削除:

    • foundstart: ラベルの後のコードブロックから pkg = nil; の行が削除されました。
    • コミットメッセージには「unnexessary initialisation」(不要な初期化)と記載されており、この pkg 変数の初期化がコードのロジック上、もはや必要ないか、あるいは別の場所で適切に初期化されるようになったため削除されたと考えられます。これにより、デッドコードの削除とコードの簡素化が実現されています。
  3. 0 から 0L への変更:

    • armove 関数と rl 関数内の複数の sprint 関数呼び出しにおいて、%-12ld フォーマット指定子で出力される値が 0 から 0L に変更されました。
    • 具体的には、bp->hdr.date (アーカイブメンバーの日付フィールド) や a.date (アーカイブヘッダの日付フィールド) に値を書き込む際に、以前は d->mtimetime(0) といったタイムスタンプが使用されていましたが、冪等なビルドのためにこれらが 0 に置き換えられました。
    • %-12ld というフォーマット指定子は long 型の引数を期待します。C言語では、0 はデフォルトで int 型として扱われるため、long 型を期待するフォーマット指定子に int 型の値を渡すと、コンパイラの警告や、場合によっては未定義動作を引き起こす可能性があります。0L と明示的に long 型のリテラルを使用することで、この型不一致の問題を解消し、コードの堅牢性を高めています。

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

--- a/src/cmd/gopack/ar.c
+++ b/src/cmd/gopack/ar.c
@@ -37,7 +37,6 @@
 #define rcmd your_rcmd
 
 #include <u.h>
-#include <time.h>
 #include <libc.h>
 #include <bio.h>
 #include <mach.h>
@@ -838,7 +837,6 @@ foundstart:
 		goto bad;
 
 	/* how big is it? */
-\tpkg = nil;
 	first = 1;
 	start = end = 0;
 	for (n=0; n<size; n+=Blinelen(b)) {
@@ -1102,7 +1100,7 @@ armove(Biobuf *b, Arfile *ap, Armember *bp)
 	for (cp = strchr(bp->hdr.name, 0);		/* blank pad on right */
 	cp < bp->hdr.name+sizeof(bp->hdr.name); cp++)
 			*cp = ' ';
-\tsprint(bp->hdr.date, "%-12ld", 0);  // was d->mtime but removed for idempotent builds
+\tsprint(bp->hdr.date, "%-12ld", 0L);  // was d->mtime but removed for idempotent builds
 	sprint(bp->hdr.uid, "%-6d", 0);
 	sprint(bp->hdr.gid, "%-6d", 0);
 	sprint(bp->hdr.mode, "%-8lo", d->mode);
@@ -1236,7 +1234,7 @@ rl(int fd)
 	len = symdefsize;
 	if(len&01)
 		len++;
-\tsprint(a.date, "%-12ld", 0);  // time(0)
+\tsprint(a.date, "%-12ld", 0L);  // time(0)
 	sprint(a.uid, "%-6d", 0);
 	sprint(a.gid, "%-6d", 0);
 	sprint(a.mode, "%-8lo", 0644L);
@@ -1273,7 +1271,7 @@ rl(int fd)
 
 	if (gflag) {
 		len = pkgdefsize;
-\tsprint(a.date, "%-12ld", 0);  // time(0)
+\tsprint(a.date, "%-12ld", 0L);  // time(0)
 		sprint(a.uid, "%-6d", 0);
 		sprint(a.gid, "%-6d", 0);
 		sprint(a.mode, "%-8lo", 0644L);

コアとなるコードの解説

  • - #include <time.h>:

    • この行の削除は、アーカイブのタイムスタンプを固定値 0 に変更したことによるものです。time.htime() 関数を提供し、システム時刻を取得するために使用されます。タイムスタンプが不要になったため、このヘッダファイルのインクルードも不要になりました。これにより、コンパイル時の依存関係が減少し、コードベースがよりスリムになります。
  • - pkg = nil;:

    • この行の削除は、pkg 変数の初期化が不要になったことを示しています。pkg はおそらく、アーカイブ内のパッケージ情報を扱うためのポインタ変数であり、以前はここで nil に初期化されていましたが、その後のコードロジックの変更により、この初期化が冗長になったか、別の場所でより適切な初期化が行われるようになったため削除されました。
  • - sprint(bp->hdr.date, "%-12ld", 0); から + sprint(bp->hdr.date, "%-12ld", 0L);:

    • この変更は、アーカイブメンバーのヘッダにある日付フィールド (bp->hdr.date) に値を書き込む部分です。
    • 以前は d->mtime (ファイルの最終更新時刻) が使用されていましたが、冪等なビルドのために 0 に変更されました。
    • %-12ld というフォーマット指定子は long 型の引数を期待します。0int 型として扱われるため、0L とすることで明示的に long 型のリテラルを渡し、型の一致を保証しています。これにより、コンパイラの警告を回避し、クロスプラットフォーム(特にPlan 9のような環境)での潜在的な問題を解消します。
  • - sprint(a.date, "%-12ld", 0); から + sprint(a.date, "%-12ld", 0L); (2箇所):

    • これらの変更は、アーカイブ全体のヘッダ (a.date) に値を書き込む部分です。
    • ここでも同様に、以前は time(0) (現在のシステム時刻) が使用されていましたが、冪等なビルドのために 0 に変更されました。
    • %-12ld フォーマット指定子との型の一致を保つため、00L に変更しています。これは、ビルドの再現性を高めると同時に、C言語の型システムにおけるベストプラクティスに従った修正です。

これらの変更は、Goのツールチェインが異なるオペレーティングシステム(特にPlan 9)でより堅牢に動作し、かつビルドの再現性(冪等性)を向上させるための重要なステップでした。

関連リンク

参考にした情報源リンク