私はclangでバグを見つけましたが、clangシステムではこのバグを実行する方法を見つけるのが難しいので、ここに投稿しています。この情報が役に立つと思います。オンラインで同様の質問を見たことがあります。
したがって、clang は間違った接続を実行します。 OpenBSD 6.3 amd64で安定しています。
モジュールの 1 つにライブラリ関数と同じ名前のグローバル変数がある場合、変数型が "int" であってもライブラリ関数呼び出しを変数に関連付けます。例:
基本(単純)モジュール "socket.cpp"、ソケット()呼び出し:
#include <stdio.h>
#include <sys/socket.h>
int
main(int argc, char * argv[]){
int result = socket(AF_INET, SOCK_DGRAM, 17);
printf("result = %d\n", result);
return 0;
}
2番目のモジュール「add.cpp」には「socket」というグローバル変数があります。
int socket = 5;
makefile/clang を使用すると、警告なしにコンパイルおよびリンクできます。ただし、プログラムを実行すると「セグメントエラー」が発生します。
逆アセンブラの実行ファイルを見ると、システム関数「ソケット」への呼び出しはありません。この変数は醜い方法で「呼び出し」されます。
このバグレポートをclangコミュニティに提出する方法を知っている人がいる場合は、どうぞ...
アップデート1
clang は次のように呼び出されます。
clang -o test socket.o add.o
アップデート2
まあ、それは予想できると思います。リンカーは2つのソケット記号をどのように区別する必要がありますか? – 矢
Microsoft コンパイラはどのように差別化されますか?技術的に難しいですか?このコードは Visual Studio で正しく実行されます。そこに問題はありません。
アップデート3
これにより、コードがこれを「呼び出し」してクラッシュします。これは間違いではありません。 – 矢
これはプログラマロジックのバグです。変数"int"を呼び出す方法は?この設計の特定の人間工学的特性は悪い。
リンカーが「呼び出し」変数「int」を参照しないのはなぜですか?これは無言の音です。これは間違ったシステム設計です。
接続プロセスのあいまいさに警告する必要があります。沈黙の行為 - 間違いの春。
答え1
これは、整数を関数として実行しようとするために発生します。int socket = 5;
関数と同じ名前を使用すると、socket()
次のようにこれを達成するより簡単な方法があります。
$ cat main.c
int main = 9;
$ clang -Wall main.c
$ ./a.out
Segmentation fault
更新:@Kusalanandaがコメントで述べたように、clangでのみ発生するわけではありません。
答え2
リンカはsocket
シンボルを整数変数として解釈します。これにより、コードがこれを「呼び出し」してクラッシュします。これは間違いではありません。
エクスポートされたすべてのシンボルを装飾するために特別な装飾スキームを使用するため、Microsoftコンパイラと連携します。このシナリオでは、C関数とグローバル変数が異なるように装飾され(?socket@@YAHHHH@Z
vs ?socket@@3HA
)、シンボル名が異なります。 * nixシステムでは、通常のC関数とグローバル変数はリマッピングを使用しません。