Cで予約済み識別子の競合する使用を検出することは可能ですか?

rkuczwara

C標準によれば、プログラムが予約済み識別子を定義または宣言する場合、動作は未定義です。予約済み識別子の1つのカテゴリは、C標準ライブラリで定義された外部リンケージを持つ識別子です。

未定義の動作を持つプログラムの例として、次のことを考慮してください。file1.cは、time.hで宣言された標準ライブラリの関数timeと競合する外部リンケージで名前が付けられた変数を定義します。time

file1.c:

int time;

int foo( void )
{
    return time;
}

file2.c:

#include <time.h>
#include <stdio.h>

extern int foo( void );

int main( void )
{
    foo();
    printf( "current time = %ld\n", time( NULL ) );
    return 0;
}

プログラムをコンパイルして実行すると、timefile2.cで参照されているシンボルtimeが、Cライブラリの関数ではなく、file1.c変数にリンクされるため、セグメンテーション違反が発生します。

$ gcc -c -o file1.o file1.c
$ gcc -c -o file2.o file2.c
$ gcc -o test file1.o file2.o 
$ ./test
Segmentation fault (core dumped)

コンパイル時またはリンク時に、GCCがユーザーコード内の競合する予約済み識別子の使用を検出する方法があるかどうか疑問に思っています。私の動機は次のとおりです。ユーザーがアプリケーションにC拡張機能を記述して、コンパイルしてアプリケーションの残りの部分にリンクできるアプリケーションに取り組んでいます。ユーザーのCコードが上記の例のように予約済みの識別子を使用している場合、結果のプログラムは予測が難しい方法で失敗する可能性があります。

頭に浮かぶ解決策の1つはnm、ユーザーのオブジェクトファイルでのようなものを実行し、定義されたシンボルをCライブラリの予約済み識別子のリストと比較することです。ただし、GCCで問題を検出できるものを見つけたいと思っています。誰かがそれが可能かどうか知っていますか、または何か提案がありますか?

PSkocik

静的にリンクできるlibc実装を取得-Wl,--whole-archiveして、オブジェクトファイルにスラップすることができます。

main.c

int time=42;
int main(){}

それをlibc全体とリンクします:

$ musl-gcc main.c -static -Wl,--whole-archive

複数の定義エラーが発生した場合、またはシンボルのタイプ/サイズ/配置が変更されたという警告が表示された場合は、libcと衝突しています。

/usr/local/bin/ld: /usr/local/musl/lib/libc.a(time.lo): in function `time':
/home/petr/f/proj/bxdeps/musl/src/time/time.c:5: multiple definition of `time'; /tmp/cc3bL3pP.o:(.data+0x0): first defined here

あるいは(そしてより堅牢に)、all-of-C(all-of-posix)ヘッダーを事前にインクルードし、それと衝突している場所をコンパイラーに通知させることができます(それ以外の場合は、たまにしか実行しません)。ビルド時間がいくらか悲観的になります(ただし、POSIXをすべて含めても、C ++ヘッダーを1つでも含めてもそれほど悪くはありません))。

この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。

侵害の場合は、連絡してください[email protected]

編集
0

コメントを追加

0

関連記事

分類Dev

SyntaxError:letはFirefoxの予約済み識別子です

分類Dev

haskellで特別な(予約済み)文字を使用する方法は?

分類Dev

Firefoxで構文エラーが発生するのはなぜですか?クラスは予約済みの識別子ですか?

分類Dev

「予約済み」の識別子を作成してもよいのはいつですか。

分類Dev

byebugの予約済みキーワードと競合する変数名にアクセス/操作するにはどうすればよいですか?

分類Dev

byebugの予約済みキーワードと競合する変数名にアクセス/操作するにはどうすればよいですか?

分類Dev

マクロに渡される識別子に制約を適用することは可能ですか?

分類Dev

特定の到着/出発日と競合する予約を検索する

分類Dev

クラスメンバーの識別子として変数を使用することは可能ですか?

分類Dev

int識別子で列挙型を定義することは可能ですか?

分類Dev

識別子が予約語でない場合やスペースを含む場合、なぜBACKTICKSを使用する必要があるのですか?

分類Dev

xml出力で予約済みのCOBOL名を使用する

分類Dev

ガベージコレクターを実行すると、予約済みRAM Javaが増加することがあるのはなぜですか?

分類Dev

競合ファイルの競合領域でのみ「ours」を取得する場合に、選択的な「gitcheckout--ours」を実行することは可能ですか?

分類Dev

予約済みIPをAzureContainer Instances(ACI)に割り当てることはできますか?

分類Dev

Informixで識別子として使用されている予約語をエスケープするにはどうすればよいですか?

分類Dev

電子メールの「受信済み」フィールドを偽造することは可能ですか?

分類Dev

Mockitoでテスト済みのオブジェクトメソッド呼び出しを検証することは可能ですか?

分類Dev

古いCコードとその中の予約済みキーワードをC ++でリンクするにはどうすればよいですか?

分類Dev

文字列とともに変数を使用して別の変数を識別することは可能ですか?

分類Dev

このJavaプロジェクトでは、言語の予約語を識別子としてどのように使用していますか?

分類Dev

約束の連鎖の終わりを検出することは可能ですか?

分類Dev

登録済みのCPUで標準RAMを使用することは可能ですか?

分類Dev

OpenCLの予約済みデータ型とは何ですか?

分類Dev

onkeyupとonpasteの間で1つのイベントのみを検出することは可能ですか?

分類Dev

onkeyupとonpasteの間で1つのイベントのみを検出することは可能ですか?

分類Dev

hibernate @ Formulaで予約済みテーブル列を使用するにはどうすればよいですか

分類Dev

予約済みの偽色で灰色の cmap を変更するにはどうすればよいですか?

分類Dev

FortranのSelectTypeを使用してタイプを識別および区別することは可能ですか?

Related 関連記事

  1. 1

    SyntaxError:letはFirefoxの予約済み識別子です

  2. 2

    haskellで特別な(予約済み)文字を使用する方法は?

  3. 3

    Firefoxで構文エラーが発生するのはなぜですか?クラスは予約済みの識別子ですか?

  4. 4

    「予約済み」の識別子を作成してもよいのはいつですか。

  5. 5

    byebugの予約済みキーワードと競合する変数名にアクセス/操作するにはどうすればよいですか?

  6. 6

    byebugの予約済みキーワードと競合する変数名にアクセス/操作するにはどうすればよいですか?

  7. 7

    マクロに渡される識別子に制約を適用することは可能ですか?

  8. 8

    特定の到着/出発日と競合する予約を検索する

  9. 9

    クラスメンバーの識別子として変数を使用することは可能ですか?

  10. 10

    int識別子で列挙型を定義することは可能ですか?

  11. 11

    識別子が予約語でない場合やスペースを含む場合、なぜBACKTICKSを使用する必要があるのですか?

  12. 12

    xml出力で予約済みのCOBOL名を使用する

  13. 13

    ガベージコレクターを実行すると、予約済みRAM Javaが増加することがあるのはなぜですか?

  14. 14

    競合ファイルの競合領域でのみ「ours」を取得する場合に、選択的な「gitcheckout--ours」を実行することは可能ですか?

  15. 15

    予約済みIPをAzureContainer Instances(ACI)に割り当てることはできますか?

  16. 16

    Informixで識別子として使用されている予約語をエスケープするにはどうすればよいですか?

  17. 17

    電子メールの「受信済み」フィールドを偽造することは可能ですか?

  18. 18

    Mockitoでテスト済みのオブジェクトメソッド呼び出しを検証することは可能ですか?

  19. 19

    古いCコードとその中の予約済みキーワードをC ++でリンクするにはどうすればよいですか?

  20. 20

    文字列とともに変数を使用して別の変数を識別することは可能ですか?

  21. 21

    このJavaプロジェクトでは、言語の予約語を識別子としてどのように使用していますか?

  22. 22

    約束の連鎖の終わりを検出することは可能ですか?

  23. 23

    登録済みのCPUで標準RAMを使用することは可能ですか?

  24. 24

    OpenCLの予約済みデータ型とは何ですか?

  25. 25

    onkeyupとonpasteの間で1つのイベントのみを検出することは可能ですか?

  26. 26

    onkeyupとonpasteの間で1つのイベントのみを検出することは可能ですか?

  27. 27

    hibernate @ Formulaで予約済みテーブル列を使用するにはどうすればよいですか

  28. 28

    予約済みの偽色で灰色の cmap を変更するにはどうすればよいですか?

  29. 29

    FortranのSelectTypeを使用してタイプを識別および区別することは可能ですか?

ホットタグ

アーカイブ