C/C++:errno に関連付けられた文字列の最大サイズ (コンパイル時)



質問


08 に関連付けられた文字列の最大サイズを取得する方法はありますか コンパイル時(プリプロセッサ時はさらに良いでしょう)?例えば。 18 の上限 ?


私の考え


私が考えることができる最善の方法は、プログラムを実行して int の範囲、各ロケールでブルートフォース検索を実行し、各 {errno, locale} ペアに関連付けられた文字列を取得し、そのサイズを取得し、ヘッダーを生成することですそのシステムで、それをたとえばにフックします。 makefile や autoconf など。それを行うためのより良い方法は考えられませんが、そうであるとはばかげているようです。システムの標準ライブラリには、暗黙的であっても、その情報が組み込まれています。その情報を得る良い方法は本当にないのでしょうか?


わかりました、C および/または C++ 標準が、実行時に生成されるエラー文字列を許可する可能性があることを認めます。状況に応じたメッセージ (例:25 39 の場合、他のランタイム メタデータ セットから派生した文字列を与える が最後に設定された、または何か) - それが かどうかわからない 許可されており、実際にはそのような実装を歓迎しますが、既存の実装を聞いたことがないか、特定の {48 に対して複数の文字列を持っていました , locale} ペア。


モチベーション


文脈上、私が具体的に望んでいたのは(ただし、コメントの中で議論されたように、この質問はより一般的な方法で価値があると思います)、この質問につながったのは、 56 システムコール/関数 68 で .私の特定のユースケースでは、70 の文字列を使用していました そして 87 -リンクされた文字列。これにより、「最悪の場合」の長さが 97 に設定されました + 105 + 112 ).


私が参照したすべての *nix ドキュメントは 127 を示しているようです 131 でエラーが発生します (または、この場合の違いがほとんど役に立たないため、「可能性があります」)。 144 に設定 157 の合計の場合 値がオーバーフロー 163 .直感的に、私はすべての 176 を知っています 私が見た文字列は非常に短く、実際にはこれは問題ではありません。しかし、この仮定が偽である可能性がある場合、コードが何らかのシステムで不思議なことにエラーをまったく出力しないことを望んでいません。そのため、そのようなケースを処理するコードを書きましたが、同時に、一般的に明らかに必要としないプラットフォーム用に追加のコードをコンパイルすることは望んでいません.


これまでの回答とコメントを組み合わせた入力により、私の特定のユースケースでは、「正しい」解決策は、わいせつに長いメッセージを切り捨てることであると考える傾向があります-しかし、これが私が最初に行った方法について質問した理由です:このような情報は、バッファのサイズを 184 に選択するのにも役立ちます /195 (*nix/Windows それぞれ)、否定的な回答 (たとえば、「あなたには本当にできない」) でさえ、他の人の教育に役立つと私は考えています。


関連


この質問には、200 で指定された文字列に対する回答が含まれています VxWorks の場合ですが、それをすべてのシステムに一般化するのは気が進まない.


答え:


ビルド対象の C ライブラリは、実行対象の C ライブラリと同じ (ABI 互換の C ライブラリが使用される可能性があります) または正確なバージョン (GNU/Linux では glibc 2.2.5 と glibc 2.23 を検討してください) ではない可能性があります。 217 から返されるロケール依存の文字列の最大サイズ プロセス実行中の実行時にのみ実行できます。これに加えて、ロケールの翻訳はいつでもターゲット システムで更新される可能性があり、これもまた、この上限の事前計算を無効にします。


残念ながら、227 によって返される値が確実に返されるという保証はありません。 プロセスの存続期間中は一定であるため、後で変更される可能性があり、境界の初期の計算が無効になります。


strerror_r を使用してエラー文字列を保存し、sterror を呼び出してコピー中に文字列の結果を変更する可能性のある非マルチスレッド対応ライブラリの問題を回避することをお勧めします。次に、その場で文字列を翻訳する代わりに、保存された結果を使用し、236 に切り捨てる可能性があります。 (実際には決して起こりません)。