[インデックス 14427] ファイルの概要
このコミットは、Go言語のランタイムにおけるCGO(C言語との相互運用)機能に関して、Windows環境でのコンパイルエラーを修正するものです。具体的には、CFLAGS -Wall -Werror
オプションを付けてコンパイルした際に発生する警告がエラーとして扱われる問題に対処しています。また、cmd/ld/pe.c
内の古くなったコメントも修正しています。
コミット
commit 3513d8406815c090b80e1bba543617af60c60e3e
Author: Shenghou Ma <minux.ma@gmail.com>
Date: Sun Nov 18 02:06:08 2012 +0800
runtime/cgo: fix compilation on Windows with CFLAGS -Wall -Werror
also fix one out-of-date comment in cmd/ld/pe.c as well.
R=golang-dev, alex.brainman
CC=golang-dev
https://golang.org/cl/6843061
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/3513d8406815c090b80e1bba543617af60c60e3e
元コミット内容
runtime/cgo: fix compilation on Windows with CFLAGS -Wall -Werror
also fix one out-of-date comment in cmd/ld/pe.c as well.
R=golang-dev, alex.brainman
CC=golang-dev
https://golang.org/cl/6843061
変更の背景
この変更の背景には、主に以下の2点があります。
- コンパイラ警告の厳格化への対応: C/C++のコンパイルにおいて
-Wall
(全ての警告を有効にする) および-Werror
(警告をエラーとして扱う) フラグは、コード品質を高め、潜在的なバグを早期に発見するために広く用いられます。Goのランタイム、特にCGO関連のコードはC言語で書かれている部分が多く、これらのフラグを適用した際に、以前は警告として扱われていたものがエラーとなり、コンパイルが失敗する問題が発生していました。このコミットは、そのエラーを解消し、より厳格なコンパイル設定でもGoがWindows上で正しくビルドできるようにすることを目的としています。 - コメントの陳腐化:
src/cmd/ld/pe.c
内のコメントが、GoのランタイムやCGOのスタックサイズ管理の変更に伴い、現状と合致しなくなっていました。このコミットは、コードの現状を正確に反映するようにコメントを更新し、将来のメンテナがコードを理解しやすくすることを意図しています。
前提知識の解説
GoにおけるCGO
CGOは、GoプログラムからC言語のコードを呼び出したり、逆にC言語のコードからGoの関数を呼び出したりするためのGoの機能です。これにより、既存のCライブラリをGoプロジェクトで再利用したり、Goでは実装が難しい低レベルな操作を行ったりすることが可能になります。CGOを使用する際には、GoコンパイラがCコンパイラ(GCCなど)と連携して、Cコードをコンパイルし、Goの実行可能ファイルにリンクします。
-Wall -Werror
コンパイラフラグ
-Wall
: GCC (GNU Compiler Collection) などのC/C++コンパイラで使用されるオプションで、"全ての警告 (All warnings)" を有効にします。これにより、潜在的な問題や非推奨の構文など、様々な種類の警告が出力されるようになります。開発者はこれらの警告を修正することで、より堅牢で移植性の高いコードを書くことができます。-Werror
: このオプションは、コンパイラが出力する全ての警告をエラーとして扱います。つまり、警告が一つでもあれば、コンパイルは失敗します。これは、開発プロセスにおいて警告を無視しないように強制し、コード品質を厳しく保つための一般的なプラクティスです。
Windowsにおけるスレッド作成 (_beginthread
と CreateThread
)
Windows環境で新しいスレッドを作成する際には、主に CreateThread
と _beginthread
(または _beginthreadex
) の2つの関数が使われます。
CreateThread
: Windows APIの一部であり、OSレベルでスレッドを作成します。しかし、Cランタイムライブラリ(CRT)の内部状態(例えば、errno
やmalloc
のヒープ)はスレッド間で共有されるため、CreateThread
を直接使用すると、CRTの整合性問題を引き起こす可能性があります。_beginthread
: Microsoft Visual C++のCRTが提供する関数で、CreateThread
をラップしています。この関数は、新しいスレッドがCRTの内部状態を正しく初期化し、安全にCRT関数を使用できるようにします。GoのCGOランタイムがWindows上でCスレッドを作成する場合、CRTの整合性を保つために_beginthread
を使用するのが一般的です。
_beginthread
のスレッドエントリポイント関数(新しいスレッドで実行される関数)のシグネチャは、通常 void (*start_address)(void *)
または unsigned (__stdcall *start_address)(void *)
の形式を期待します。特に void
を返す関数は、戻り値がないことを明示します。
PE (Portable Executable) フォーマット
PEフォーマットは、Windowsオペレーティングシステムで使用される実行可能ファイル、オブジェクトコード、DLL (Dynamic Link Library) などのファイル形式です。Goのリンカ (cmd/ld
) は、Windows向けの実行可能ファイルを生成する際に、このPEフォーマットに従って出力します。PEファイルには、コード、データ、リソース、そしてスタックサイズなどの実行時情報が含まれます。
技術的詳細
このコミットの技術的詳細は、主にCGOランタイムがWindows上でスレッドを扱う方法と、Cコンパイラの厳格なチェックにどのように対応したかに集約されます。
-
threadentry
関数のシグネチャ変更:- 変更前:
static void *threadentry(void*);
- 変更後:
static void threadentry(void*);
- 元のシグネチャ
void *threadentry(void*)
は、関数がvoid*
型のポインタを返すことを示しています。しかし、threadentry
関数は実際には何も値を返していませんでした(return nil;
がコメントアウトされているか、単にreturn;
がない状態)。多くのCコンパイラでは、戻り値の型がvoid
以外であるにもかかわらず、return
ステートメントがない場合、警告を発します。-Werror
が有効な場合、この警告はエラーとなりコンパイルが失敗します。 - 新しいシグネチャ
void threadentry(void*)
は、関数が何も値を返さないことを明示しています。これにより、コンパイラは戻り値がないことについて警告を発しなくなり、-Werror
環境下でもコンパイルが成功するようになります。 - この変更は、
_beginthread
関数が期待するスレッドエントリポイントのシグネチャにも合致しています。_beginthread
は、スレッド関数がvoid
を返すことを許容します。
- 変更前:
-
return nil;
の削除:threadentry
関数のシグネチャをvoid
に変更したことに伴い、関数末尾にあったreturn nil;
ステートメントは不要になります。void
型の関数は値を返すことができないため、return nil;
は構文エラーとなります。このコミットでは、この行を削除することで、新しいシグネチャとの整合性を保っています。
-
<process.h>
のインクルード:_beginthread
関数は、WindowsのCランタイムライブラリの一部であり、そのプロトタイプは<process.h>
ヘッダファイルで宣言されています。このコミットでは、gcc_windows_386.c
とgcc_windows_amd64.c
の両方に<process.h>
をインクルードすることで、_beginthread
の使用に必要な宣言が提供され、コンパイラが関数のプロトタイプを知らないことによる警告やエラーを防いでいます。
-
src/cmd/ld/pe.c
のコメント修正:- このファイルはGoのリンカの一部で、WindowsのPE実行可能ファイルを生成する際の設定を扱います。特に、スタックの予約サイズに関するコメントが古くなっていました。
- 変更前:
// change them in runtime/cgo/windows_386/amd64.c as well.
- 変更後:
// change STACKSIZE in runtime/cgo/gcc_windows_{386,amd64}.c as well.
- この修正は、スタックサイズが定義されているファイルパスと変数名が変更されたことを反映しています。これにより、将来的にスタックサイズを変更する必要がある開発者が、正しい場所を特定できるようになります。
コアとなるコードの変更箇所
src/cmd/ld/pe.c
--- a/src/cmd/ld/pe.c
+++ b/src/cmd/ld/pe.c
@@ -659,7 +659,7 @@ asmbpe(void)
// for other threads we specify stack size in runtime explicitly
// (runtime knows whether cgo is enabled or not).
// If you change stack reserve sizes here,
- // change them in runtime/cgo/windows_386/amd64.c as well.
+ // change STACKSIZE in runtime/cgo/gcc_windows_{386,amd64}.c as well.
if(!iscgo) {
set(SizeOfStackReserve, 0x00010000);
set(SizeOfStackCommit, 0x0000ffff);
src/pkg/runtime/cgo/gcc_windows_386.c
--- a/src/pkg/runtime/cgo/gcc_windows_386.c
+++ b/src/pkg/runtime/cgo/gcc_windows_386.c
@@ -4,9 +4,10 @@
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
+#include <process.h>
#include "libcgo.h"
-static void *threadentry(void*);
+static void threadentry(void*);
/* 1MB is default stack size for 32-bit Windows.
Allocation granularity on Windows is typically 64 KB.
@@ -28,7 +29,7 @@ libcgo_sys_thread_start(ThreadStart *ts)
_beginthread(threadentry, 0, ts);
}
-static void*
+static void
threadentry(void *v)
{
ThreadStart ts;
@@ -55,5 +56,4 @@ threadentry(void *v)
crosscall_386(ts.fn);
LocalFree(tls0);
-\treturn nil;
}
src/pkg/runtime/cgo/gcc_windows_amd64.c
--- a/src/pkg/runtime/cgo/gcc_windows_amd64.c
+++ b/src/pkg/runtime/cgo/gcc_windows_amd64.c
@@ -4,9 +4,10 @@
#define WIN64_LEAN_AND_MEAN
#include <windows.h>
+#include <process.h>
#include "libcgo.h"
-static void *threadentry(void*);
+static void threadentry(void*);
/* 2MB is default stack size for 64-bit Windows.
Allocation granularity on Windows is typically 64 KB.
@@ -28,7 +29,7 @@ libcgo_sys_thread_start(ThreadStart *ts)\n _beginthread(threadentry, 0, ts);\n }\n \n-static void*\n+static void\n threadentry(void *v)\n {\n ThreadStart ts;\n@@ 53,5 +54,4 @@ threadentry(void *v)\n );\n \n crosscall_amd64(ts.fn);\n-\treturn nil;\n }\n```
## コアとなるコードの解説
### `src/cmd/ld/pe.c` の変更
このファイルはGoのリンカの一部であり、Windowsの実行可能ファイル(PEフォーマット)を生成する際のスタックサイズ設定に関連するコメントを修正しています。
* **変更前**: `// change them in runtime/cgo/windows_386/amd64.c as well.`
* **変更後**: `// change STACKSIZE in runtime/cgo/gcc_windows_{386,amd64}.c as well.`
この変更は、スタックサイズが定義されているCGOランタイムのファイル名と、その中の変数名が変更されたことを反映しています。これにより、開発者がスタックサイズ関連のコードを追跡する際に、より正確な情報が提供されます。
### `src/pkg/runtime/cgo/gcc_windows_386.c` および `src/pkg/runtime/cgo/gcc_windows_amd64.c` の変更
これらのファイルは、それぞれ32ビットおよび64ビットWindows環境におけるCGOランタイムのスレッド管理を担当しています。変更内容は両ファイルでほぼ同じです。
1. **`#include <process.h>` の追加**:
* `_beginthread` 関数を使用するために必要なヘッダファイル `<process.h>` が追加されました。これにより、`_beginthread` のプロトタイプがコンパイラに認識され、コンパイル時の警告やエラーが回避されます。
2. **`threadentry` 関数のシグネチャ変更**:
* **変更前**: `static void *threadentry(void*);`
* **変更後**: `static void threadentry(void*);`
* `threadentry` は、`_beginthread` によって新しいスレッドで実行されるエントリポイント関数です。元のシグネチャは `void*` を返すと宣言していましたが、実際には何も返していませんでした。Cコンパイラは、戻り値の型が `void` 以外であるにもかかわらず `return` ステートメントがない場合に警告を発します。この警告は `-Werror` フラグが有効な場合にエラーとなるため、シグネチャを `void` に変更することで、関数が何も返さないことを明示し、コンパイルエラーを解消しました。
3. **`return nil;` の削除**:
* `threadentry` 関数の本体の最後にあった `return nil;` が削除されました。`threadentry` の戻り値の型が `void` に変更されたため、値を返すことはできなくなります。この行を削除することで、新しい関数シグネチャとの整合性が保たれます。
これらの変更により、GoのCGOランタイムは、Windows環境で `-Wall -Werror` のような厳格なコンパイラフラグを使用しても、警告やエラーなしにコンパイルできるようになり、ビルドプロセスの堅牢性が向上しました。
## 関連リンク
* Go Programming Language: [https://golang.org/](https://golang.org/)
* Go CGO Documentation: [https://pkg.go.dev/cmd/cgo](https://pkg.go.dev/cmd/cgo)
* GCC Manual (Warning Options): [https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html](https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html)
* Microsoft Docs: `_beginthread`, `_beginthreadex`: [https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/beginthread-beginthreadex?view=msvc-170](https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/beginthread-beginthreadex?view=msvc-170)
* Microsoft Docs: `CreateThread` function: [https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-createthread](https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-createthread)
## 参考にした情報源リンク
* Goの公式ドキュメントとソースコード
* GCCのドキュメント
* Microsoft Windows APIのドキュメント
* C言語の標準に関する一般的な知識
* Stack Overflowなどの開発者コミュニティの議論 (特定のURLは記載しないが、一般的な知識として参照)
# [インデックス 14427] ファイルの概要
このコミットは、Go言語のランタイムにおけるCGO(C言語との相互運用)機能に関して、Windows環境でのコンパイルエラーを修正するものです。具体的には、`CFLAGS -Wall -Werror` オプションを付けてコンパイルした際に発生する警告がエラーとして扱われる問題に対処しています。また、`cmd/ld/pe.c` 内の古くなったコメントも修正しています。
## コミット
commit 3513d8406815c090b80e1bba543617af60c60e3e Author: Shenghou Ma minux.ma@gmail.com Date: Sun Nov 18 02:06:08 2012 +0800
runtime/cgo: fix compilation on Windows with CFLAGS -Wall -Werror
also fix one out-of-date comment in cmd/ld/pe.c as well.
R=golang-dev, alex.brainman
CC=golang-dev
https://golang.org/cl/6843061
## GitHub上でのコミットページへのリンク
[https://github.com/golang/go/commit/3513d8406815c090b80e1bba543617af60c60e3e](https://github.com/golang/go/commit/3513d8406815c090b80e1bba543617af60c60e3e)
## 元コミット内容
runtime/cgo: fix compilation on Windows with CFLAGS -Wall -Werror also fix one out-of-date comment in cmd/ld/pe.c as well.
R=golang-dev, alex.brainman CC=golang-dev https://golang.org/cl/6843061
## 変更の背景
この変更の背景には、主に以下の2点があります。
1. **コンパイラ警告の厳格化への対応**: C/C++のコンパイルにおいて `-Wall` (全ての警告を有効にする) および `-Werror` (警告をエラーとして扱う) フラグは、コード品質を高め、潜在的なバグを早期に発見するために広く用いられます。Goのランタイム、特にCGO関連のコードはC言語で書かれている部分が多く、これらのフラグを適用した際に、以前は警告として扱われていたものがエラーとなり、コンパイルが失敗する問題が発生していました。このコミットは、そのエラーを解消し、より厳格なコンパイル設定でもGoがWindows上で正しくビルドできるようにすることを目的としています。
2. **コメントの陳腐化**: `src/cmd/ld/pe.c` 内のコメントが、GoのランタイムやCGOのスタックサイズ管理の変更に伴い、現状と合致しなくなっていました。このコミットは、コードの現状を正確に反映するようにコメントを更新し、将来のメンテナがコードを理解しやすくすることを意図しています。
## 前提知識の解説
### GoにおけるCGO
CGOは、GoプログラムからC言語のコードを呼び出したり、逆にC言語のコードからGoの関数を呼び出したりするためのGoの機能です。これにより、既存のCライブラリをGoプロジェクトで再利用したり、Goでは実装が難しい低レベルな操作を行ったりすることが可能になります。CGOを使用する際には、GoコンパイラがCコンパイラ(GCCなど)と連携して、Cコードをコンパイルし、Goの実行可能ファイルにリンクします。
### `-Wall -Werror` コンパイラフラグ
* **`-Wall`**: GCC (GNU Compiler Collection) などのC/C++コンパイラで使用されるオプションで、"全ての警告 (All warnings)" を有効にします。これにより、潜在的な問題や非推奨の構文など、様々な種類の警告が出力されるようになります。開発者はこれらの警告を修正することで、より堅牢で移植性の高いコードを書くことができます。
* **`-Werror`**: このオプションは、コンパイラが出力する全ての警告をエラーとして扱います。つまり、警告が一つでもあれば、コンパイルは失敗します。これは、開発プロセスにおいて警告を無視しないように強制し、コード品質を厳しく保つための一般的なプラクティスです。
### Windowsにおけるスレッド作成 (`_beginthread` と `CreateThread`)
Windows環境で新しいスレッドを作成する際には、主に `CreateThread` と `_beginthread` (または `_beginthreadex`) の2つの関数が使われます。
* **`CreateThread`**: Windows APIの一部であり、OSレベルでスレッドを作成します。しかし、Cランタイムライブラリ(CRT)の内部状態(例えば、`errno` や `malloc` のヒープ)はスレッド間で共有されるため、`CreateThread` を直接使用すると、CRTの整合性問題を引き起こす可能性があります。
* **`_beginthread`**: Microsoft Visual C++のCRTが提供する関数で、`CreateThread` をラップしています。この関数は、新しいスレッドがCRTの内部状態を正しく初期化し、安全にCRT関数を使用できるようにします。GoのCGOランタイムがWindows上でCスレッドを作成する場合、CRTの整合性を保つために `_beginthread` を使用するのが一般的です。
`_beginthread` のスレッドエントリポイント関数(新しいスレッドで実行される関数)のシグネチャは、通常 `void (*start_address)(void *)` または `unsigned (__stdcall *start_address)(void *)` の形式を期待します。特に `void` を返す関数は、戻り値がないことを明示します。
### PE (Portable Executable) フォーマット
PEフォーマットは、Windowsオペレーティングシステムで使用される実行可能ファイル、オブジェクトコード、DLL (Dynamic Link Library) などに用いられるファイル形式です。Goのリンカ (`cmd/ld`) は、Windows向けの実行可能ファイルを生成する際に、このPEフォーマットに従って出力します。PEファイルには、コード、データ、リソース、そしてスタックサイズなどの実行時情報が含まれます。
## 技術的詳細
このコミットの技術的詳細は、主にCGOランタイムがWindows上でスレッドを扱う方法と、Cコンパイラの厳格なチェックにどのように対応したかに集約されます。
1. **`threadentry` 関数のシグネチャ変更**:
* 変更前: `static void *threadentry(void*);`
* 変更後: `static void threadentry(void*);`
* 元のシグネチャ `void *threadentry(void*)` は、関数が `void*` 型のポインタを返すことを示しています。しかし、`threadentry` 関数は実際には何も値を返していませんでした(`return nil;` がコメントアウトされているか、単に `return;` がない状態)。多くのCコンパイラでは、戻り値の型が `void` 以外であるにもかかわらず、`return` ステートメントがない場合、警告を発します。`-Werror` が有効な場合、この警告はエラーとなりコンパイルが失敗します。
* 新しいシグネチャ `void threadentry(void*)` は、関数が何も値を返さないことを明示しています。これにより、コンパイラは戻り値がないことについて警告を発しなくなり、`-Werror` 環境下でもコンパイルが成功するようになります。
* この変更は、`_beginthread` 関数が期待するスレッドエントリポイントのシグネチャにも合致しています。`_beginthread` は、スレッド関数が `void` を返すことを許容します。
2. **`return nil;` の削除**:
* `threadentry` 関数のシグネチャを `void` に変更したことに伴い、関数末尾にあった `return nil;` ステートメントは不要になります。`void` 型の関数は値を返すことができないため、`return nil;` は構文エラーとなります。このコミットでは、この行を削除することで、新しいシグネチャとの整合性を保っています。
3. **`<process.h>` のインクルード**:
* `_beginthread` 関数は、WindowsのCランタイムライブラリの一部であり、そのプロトタイプは `<process.h>` ヘッダファイルで宣言されています。このコミットでは、`gcc_windows_386.c` と `gcc_windows_amd64.c` の両方に `<process.h>` をインクルードすることで、`_beginthread` の使用に必要な宣言が提供され、コンパイラが関数のプロトタイプを知らないことによる警告やエラーを防いでいます。
4. **`src/cmd/ld/pe.c` のコメント修正**:
* このファイルはGoのリンカの一部で、WindowsのPE実行可能ファイルを生成する際の設定を扱います。特に、スタックの予約サイズに関するコメントが古くなっていました。
* 変更前: `// change them in runtime/cgo/windows_386/amd64.c as well.`
* 変更後: `// change STACKSIZE in runtime/cgo/gcc_windows_{386,amd64}.c as well.`
* この修正は、スタックサイズが定義されているファイルパスと変数名が変更されたことを反映しています。これにより、将来的にスタックサイズを変更する必要がある開発者が、正しい場所を特定できるようになります。
## コアとなるコードの変更箇所
### `src/cmd/ld/pe.c`
```diff
--- a/src/cmd/ld/pe.c
+++ b/src/cmd/ld/pe.c
@@ -659,7 +659,7 @@ asmbpe(void)
// for other threads we specify stack size in runtime explicitly
// (runtime knows whether cgo is enabled or not).
// If you change stack reserve sizes here,
- // change them in runtime/cgo/windows_386/amd64.c as well.
+ // change STACKSIZE in runtime/cgo/gcc_windows_{386,amd64}.c as well.
if(!iscgo) {
set(SizeOfStackReserve, 0x00010000);
set(SizeOfStackCommit, 0x0000ffff);
src/pkg/runtime/cgo/gcc_windows_386.c
--- a/src/pkg/runtime/cgo/gcc_windows_386.c
+++ b/src/pkg/runtime/cgo/gcc_windows_386.c
@@ -4,9 +4,10 @@
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
+#include <process.h>
#include "libcgo.h"
-static void *threadentry(void*);
+static void threadentry(void*);
/* 1MB is default stack size for 32-bit Windows.
Allocation granularity on Windows is typically 64 KB.
@@ -28,7 +29,7 @@ libcgo_sys_thread_start(ThreadStart *ts)
_beginthread(threadentry, 0, ts);
}
-static void*
+static void
threadentry(void *v)
{
ThreadStart ts;
@@ -55,5 +56,4 @@ threadentry(void *v)
crosscall_386(ts.fn);
LocalFree(tls0);
-\treturn nil;
}
src/pkg/runtime/cgo/gcc_windows_amd64.c
--- a/src/pkg/runtime/cgo/gcc_windows_amd64.c
+++ b/src/pkg/runtime/cgo/gcc_windows_amd64.c
@@ -4,9 +4,10 @@
#define WIN64_LEAN_AND_MEAN
#include <windows.h>
+#include <process.h>
#include "libcgo.h"
-static void *threadentry(void*);
+static void threadentry(void*);
/* 2MB is default stack size for 64-bit Windows.
Allocation granularity on Windows is typically 64 KB.
@@ -28,7 +29,7 @@ libcgo_sys_thread_start(ThreadStart *ts)\n _beginthread(threadentry, 0, ts);\n }\n \n-static void*\n+static void\n threadentry(void *v)\n {\n ThreadStart ts;\n@@ 53,5 +54,4 @@ threadentry(void *v)\n );\n \n crosscall_amd64(ts.fn);\n-\treturn nil;
}\n```
## コアとなるコードの解説
### `src/cmd/ld/pe.c` の変更
このファイルはGoのリンカの一部であり、Windowsの実行可能ファイル(PEフォーマット)を生成する際のスタックサイズ設定に関連するコメントを修正しています。
* **変更前**: `// change them in runtime/cgo/windows_386/amd64.c as well.`
* **変更後**: `// change STACKSIZE in runtime/cgo/gcc_windows_{386,amd64}.c as well.`
この変更は、スタックサイズが定義されているCGOランタイムのファイル名と、その中の変数名が変更されたことを反映しています。これにより、開発者がスタックサイズ関連のコードを追跡する際に、より正確な情報が提供されます。
### `src/pkg/runtime/cgo/gcc_windows_386.c` および `src/pkg/runtime/cgo/gcc_windows_amd64.c` の変更
これらのファイルは、それぞれ32ビットおよび64ビットWindows環境におけるCGOランタイムのスレッド管理を担当しています。変更内容は両ファイルでほぼ同じです。
1. **`#include <process.h>` の追加**:
* `_beginthread` 関数を使用するために必要なヘッダファイル `<process.h>` が追加されました。これにより、`_beginthread` のプロトタイプがコンパイラに認識され、コンパイル時の警告やエラーが回避されます。
2. **`threadentry` 関数のシグネチャ変更**:
* **変更前**: `static void *threadentry(void*);`
* **変更後**: `static void threadentry(void*);`
* `threadentry` は、`_beginthread` によって新しいスレッドで実行されるエントリポイント関数です。元のシグネチャは `void*` を返すと宣言していましたが、実際には何も返していませんでした。Cコンパイラは、戻り値の型が `void` 以外であるにもかかわらず `return` ステートメントがない場合に警告を発します。この警告は `-Werror` フラグが有効な場合にエラーとなるため、シグネチャを `void` に変更することで、関数が何も返さないことを明示し、コンパイルエラーを解消しました。
3. **`return nil;` の削除**:
* `threadentry` 関数の本体の最後にあった `return nil;` が削除されました。`threadentry` の戻り値の型が `void` に変更されたため、値を返すことはできなくなります。この行を削除することで、新しい関数シグネチャとの整合性が保たれます。
これらの変更により、GoのCGOランタイムは、Windows環境で `-Wall -Werror` のような厳格なコンパイラフラグを使用しても、警告やエラーなしにコンパイルできるようになり、ビルドプロセスの堅牢性が向上しました。
## 関連リンク
* Go Programming Language: [https://golang.org/](https://golang.org/)
* Go CGO Documentation: [https://pkg.go.dev/cmd/cgo](https://pkg.go.dev/cmd/cgo)
* GCC Manual (Warning Options): [https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html](https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html)
* Microsoft Docs: `_beginthread`, `_beginthreadex`: [https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/beginthread-beginthreadex?view=msvc-170](https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/beginthread-beginthreadex?view=msvc-170)
* Microsoft Docs: `CreateThread` function: [https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-createthread](https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-createthread)
## 参考にした情報源リンク
* Goの公式ドキュメントとソースコード
* GCCのドキュメント
* Microsoft Windows APIのドキュメント
* C言語の標準に関する一般的な知識
* Stack Overflowなどの開発者コミュニティの議論 (特定のURLは記載しないが、一般的な知識として参照)
# [インデックス 14427] ファイルの概要
このコミットは、Go言語のランタイムにおけるCGO(C言語との相互運用)機能に関して、Windows環境でのコンパイルエラーを修正するものです。具体的には、`CFLAGS -Wall -Werror` オプションを付けてコンパイルした際に発生する警告がエラーとして扱われる問題に対処しています。また、`cmd/ld/pe.c` 内の古くなったコメントも修正しています。
## コミット
commit 3513d8406815c090b80e1bba543617af60c60e3e Author: Shenghou Ma minux.ma@gmail.com Date: Sun Nov 18 02:06:08 2012 +0800
runtime/cgo: fix compilation on Windows with CFLAGS -Wall -Werror
also fix one out-of-date comment in cmd/ld/pe.c as well.
R=golang-dev, alex.brainman
CC=golang-dev
https://golang.org/cl/6843061
## GitHub上でのコミットページへのリンク
[https://github.com/golang/go/commit/3513d8406815c090b80e1bba543617af60c60e3e](https://github.com/golang/go/commit/3513d8406815c090b80e1bba543617af60c60e3e)
## 元コミット内容
runtime/cgo: fix compilation on Windows with CFLAGS -Wall -Werror also fix one out-of-date comment in cmd/ld/pe.c as well.
R=golang-dev, alex.brainman CC=golang-dev https://golang.org/cl/6843061
## 変更の背景
この変更の背景には、主に以下の2点があります。
1. **コンパイラ警告の厳格化への対応**: C/C++のコンパイルにおいて `-Wall` (全ての警告を有効にする) および `-Werror` (警告をエラーとして扱う) フラグは、コード品質を高め、潜在的なバグを早期に発見するために広く用いられます。Goのランタイム、特にCGO関連のコードはC言語で書かれている部分が多く、これらのフラグを適用した際に、以前は警告として扱われていたものがエラーとなり、コンパイルが失敗する問題が発生していました。このコミットは、そのエラーを解消し、より厳格なコンパイル設定でもGoがWindows上で正しくビルドできるようにすることを目的としています。
2. **コメントの陳腐化**: `src/cmd/ld/pe.c` 内のコメントが、GoのランタイムやCGOのスタックサイズ管理の変更に伴い、現状と合致しなくなっていました。このコミットは、コードの現状を正確に反映するようにコメントを更新し、将来のメンテナがコードを理解しやすくすることを意図しています。
## 前提知識の解説
### GoにおけるCGO
CGOは、GoプログラムからC言語のコードを呼び出したり、逆にC言語のコードからGoの関数を呼び出したりするためのGoの機能です。これにより、既存のCライブラリをGoプロジェクトで再利用したり、Goでは実装が難しい低レベルな操作を行ったりすることが可能になります。CGOを使用する際には、GoコンパイラがCコンパイラ(GCCなど)と連携して、Cコードをコンパイルし、Goの実行可能ファイルにリンクします。
### `-Wall -Werror` コンパイラフラグ
* **`-Wall`**: GCC (GNU Compiler Collection) などのC/C++コンパイラで使用されるオプションで、"全ての警告 (All warnings)" を有効にします。これにより、潜在的な問題や非推奨の構文など、様々な種類の警告が出力されるようになります。開発者はこれらの警告を修正することで、より堅牢で移植性の高いコードを書くことができます。
* **`-Werror`**: このオプションは、コンパイラが出力する全ての警告をエラーとして扱います。つまり、警告が一つでもあれば、コンパイルは失敗します。これは、開発プロセスにおいて警告を無視しないように強制し、コード品質を厳しく保つための一般的なプラクティスです。
### Windowsにおけるスレッド作成 (`_beginthread` と `CreateThread`)
Windows環境で新しいスレッドを作成する際には、主に `CreateThread` と `_beginthread` (または `_beginthreadex`) の2つの関数が使われます。
* **`CreateThread`**: Windows APIの一部であり、OSレベルでスレッドを作成します。しかし、Cランタイムライブラリ(CRT)の内部状態(例えば、`errno` や `malloc` のヒープ)はスレッド間で共有されるため、`CreateThread` を直接使用すると、CRTの整合性問題を引き起こす可能性があります。
* **`_beginthread`**: Microsoft Visual C++のCRTが提供する関数で、`CreateThread` をラップしています。この関数は、新しいスレッドがCRTの内部状態を正しく初期化し、安全にCRT関数を使用できるようにします。GoのCGOランタイムがWindows上でCスレッドを作成する場合、CRTの整合性を保つために `_beginthread` を使用するのが一般的です。
`_beginthread` のスレッドエントリポイント関数(新しいスレッドで実行される関数)のシグネチャは、通常 `void (*start_address)(void *)` または `unsigned (__stdcall *start_address)(void *)` の形式を期待します。特に `void` を返す関数は、戻り値がないことを明示します。
### PE (Portable Executable) フォーマット
PEフォーマットは、Windowsオペレーティングシステムで使用される実行可能ファイル、オブジェクトコード、DLL (Dynamic Link Library) などに用いられるファイル形式です。Goのリンカ (`cmd/ld`) は、Windows向けの実行可能ファイルを生成する際に、このPEフォーマットに従って出力します。PEファイルには、コード、データ、リソース、そしてスタックサイズなどの実行時情報が含まれます。
## 技術的詳細
このコミットの技術的詳細は、主にCGOランタイムがWindows上でスレッドを扱う方法と、Cコンパイラの厳格なチェックにどのように対応したかに集約されます。
1. **`threadentry` 関数のシグネチャ変更**:
* 変更前: `static void *threadentry(void*);`
* 変更後: `static void threadentry(void*);`
* 元のシグネチャ `void *threadentry(void*)` は、関数が `void*` 型のポインタを返すことを示しています。しかし、`threadentry` 関数は実際には何も値を返していませんでした(`return nil;` がコメントアウトされているか、単に `return;` がない状態)。多くのCコンパイラでは、戻り値の型が `void` 以外であるにもかかわらず、`return` ステートメントがない場合、警告を発します。`-Werror` が有効な場合、この警告はエラーとなりコンパイルが失敗します。
* 新しいシグネチャ `void threadentry(void*)` は、関数が何も値を返さないことを明示しています。これにより、コンパイラは戻り値がないことについて警告を発しなくなり、`-Werror` 環境下でもコンパイルが成功するようになります。
* この変更は、`_beginthread` 関数が期待するスレッドエントリポイントのシグネチャにも合致しています。`_beginthread` は、スレッド関数が `void` を返すことを許容します。
2. **`return nil;` の削除**:
* `threadentry` 関数のシグネチャを `void` に変更したことに伴い、関数末尾にあった `return nil;` ステートメントは不要になります。`void` 型の関数は値を返すことができないため、`return nil;` は構文エラーとなります。このコミットでは、この行を削除することで、新しいシグネチャとの整合性を保っています。
3. **`<process.h>` のインクルード**:
* `_beginthread` 関数は、WindowsのCランタイムライブラリの一部であり、そのプロトタイプは `<process.h>` ヘッダファイルで宣言されています。このコミットでは、`gcc_windows_386.c` と `gcc_windows_amd64.c` の両方に `<process.h>` をインクルードすることで、`_beginthread` の使用に必要な宣言が提供され、コンパイラが関数のプロトタイプを知らないことによる警告やエラーを防いでいます。
4. **`src/cmd/ld/pe.c` のコメント修正**:
* このファイルはGoのリンカの一部で、WindowsのPE実行可能ファイルを生成する際の設定を扱います。特に、スタックの予約サイズに関するコメントが古くなっていました。
* 変更前: `// change them in runtime/cgo/windows_386/amd64.c as well.`
* 変更後: `// change STACKSIZE in runtime/cgo/gcc_windows_{386,amd64}.c as well.`
* この修正は、スタックサイズが定義されているファイルパスと変数名が変更されたことを反映しています。これにより、将来的にスタックサイズを変更する必要がある開発者が、正しい場所を特定できるようになります。
## コアとなるコードの変更箇所
### `src/cmd/ld/pe.c`
```diff
--- a/src/cmd/ld/pe.c
+++ b/src/cmd/ld/pe.c
@@ -659,7 +659,7 @@ asmbpe(void)
// for other threads we specify stack size in runtime explicitly
// (runtime knows whether cgo is enabled or not).
// If you change stack reserve sizes here,
- // change them in runtime/cgo/windows_386/amd64.c as well.
+ // change STACKSIZE in runtime/cgo/gcc_windows_{386,amd64}.c as well.
if(!iscgo) {
set(SizeOfStackReserve, 0x00010000);
set(SizeOfStackCommit, 0x0000ffff);
src/pkg/runtime/cgo/gcc_windows_386.c
--- a/src/pkg/runtime/cgo/gcc_windows_386.c
+++ b/src/pkg/runtime/cgo/gcc_windows_386.c
@@ -4,9 +4,10 @@
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
+#include <process.h>
#include "libcgo.h"
-static void *threadentry(void*);
+static void threadentry(void*);
/* 1MB is default stack size for 32-bit Windows.
Allocation granularity on Windows is typically 64 KB.
@@ -28,7 +29,7 @@ libcgo_sys_thread_start(ThreadStart *ts)
_beginthread(threadentry, 0, ts);
}
-static void*
+static void
threadentry(void *v)
{
ThreadStart ts;
@@ -55,5 +56,4 @@ threadentry(void *v)
crosscall_386(ts.fn);
LocalFree(tls0);
-\treturn nil;
}
src/pkg/runtime/cgo/gcc_windows_amd64.c
--- a/src/pkg/runtime/cgo/gcc_windows_amd64.c
+++ b/src/pkg/runtime/cgo/gcc_windows_amd64.c
@@ -4,9 +4,10 @@
#define WIN64_LEAN_AND_MEAN
#include <windows.h>
+#include <process.h>
#include "libcgo.h"
-static void *threadentry(void*);
+static void threadentry(void*);
/* 2MB is default stack size for 64-bit Windows.
Allocation granularity on Windows is typically 64 KB.
@@ -28,7 +29,7 @@ libcgo_sys_thread_start(ThreadStart *ts)\n _beginthread(threadentry, 0, ts);\n }\n \n-static void*\n+static void\n threadentry(void *v)\n {\n ThreadStart ts;\n@@ 53,5 +54,4 @@ threadentry(void *v)\n );\n \n crosscall_amd64(ts.fn);\n-\treturn nil;
}\n```
## コアとなるコードの解説
### `src/cmd/ld/pe.c` の変更
このファイルはGoのリンカの一部であり、Windowsの実行可能ファイル(PEフォーマット)を生成する際のスタックサイズ設定に関連するコメントを修正しています。
* **変更前**: `// change them in runtime/cgo/windows_386/amd64.c as well.`
* **変更後**: `// change STACKSIZE in runtime/cgo/gcc_windows_{386,amd64}.c as well.`
この変更は、スタックサイズが定義されているCGOランタイムのファイル名と、その中の変数名が変更されたことを反映しています。これにより、開発者がスタックサイズ関連のコードを追跡する際に、より正確な情報が提供されます。
### `src/pkg/runtime/cgo/gcc_windows_386.c` および `src/pkg/runtime/cgo/gcc_windows_amd64.c` の変更
これらのファイルは、それぞれ32ビットおよび64ビットWindows環境におけるCGOランタイムのスレッド管理を担当しています。変更内容は両ファイルでほぼ同じです。
1. **`#include <process.h>` の追加**:
* `_beginthread` 関数を使用するために必要なヘッダファイル `<process.h>` が追加されました。これにより、`_beginthread` のプロトタイプがコンパイラに認識され、コンパイル時の警告やエラーが回避されます。
2. **`threadentry` 関数のシグネチャ変更**:
* **変更前**: `static void *threadentry(void*);`
* **変更後**: `static void threadentry(void*);`
* `threadentry` は、`_beginthread` によって新しいスレッドで実行されるエントリポイント関数です。元のシグネチャは `void*` を返すと宣言していましたが、実際には何も返していませんでした。Cコンパイラは、戻り値の型が `void` 以外であるにもかかわらず `return` ステートメントがない場合に警告を発します。この警告は `-Werror` フラグが有効な場合にエラーとなるため、シグネチャを `void` に変更することで、関数が何も返さないことを明示し、コンパイルエラーを解消しました。
3. **`return nil;` の削除**:
* `threadentry` 関数の本体の最後にあった `return nil;` が削除されました。`threadentry` の戻り値の型が `void` に変更されたため、値を返すことはできなくなります。この行を削除することで、新しい関数シグネチャとの整合性が保たれます。
これらの変更により、GoのCGOランタイムは、Windows環境で `-Wall -Werror` のような厳格なコンパイラフラグを使用しても、警告やエラーなしにコンパイルできるようになり、ビルドプロセスの堅牢性が向上しました。
## 関連リンク
* Go Programming Language: [https://golang.org/](https://golang.org/)
* Go CGO Documentation: [https://pkg.go.dev/cmd/cgo](https://pkg.go.dev/cmd/cgo)
* GCC Manual (Warning Options): [https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html](https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html)
* Microsoft Docs: `_beginthread`, `_beginthreadex`: [https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/beginthread-beginthreadex?view=msvc-170](https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/beginthread-beginthreadex?view=msvc-170)
* Microsoft Docs: `CreateThread` function: [https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-createthread](https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-createthread)
## 参考にした情報源リンク
* Goの公式ドキュメントとソースコード
* GCCのドキュメント
* Microsoft Windows APIのドキュメント
* C言語の標準に関する一般的な知識
* Stack Overflowなどの開発者コミュニティの議論 (特定のURLは記載しないが、一般的な知識として参照)