2017-06-20 12 views
3

データ型に対してプログラムでフォーマット指定子を推論することはできますか?例えば、印刷は、それが自動的にない何かのように長いためである場合:私は理解してデータ型からフォーマット指定子を除外しますか?

printf("Vlaue of var is <fmt_spec> ", var); 

私もそれが

printf("Name is %s",int_val); //Oops, int_val would be treated as an address 

printf("Name is %s, DOB is",name,dob); // missed %d for dob 

printf("Name is %s DOB is %d", name);//Missed printing DOB 

のようなものので、開発者の一部に多少の誤差を低減するであろうと感じている後者の二つ警告はありますが、ほとんどの場合問題になるのでエラーがスローされた方が良いとは思いませんか?あるいは、私は何かを逃しているのですか、そうするためにすでに構築されていますか?

+1

一部のコンパイラ(GCC、Clang)は、フォーマットと引数が一致していないことを警告します。しかし、あなたの質問に答えるには:いいえ、それは本当に可能ではありません。 Cには[イントロスペクション](https://en.wikipedia.org/wiki/Type_introspection)や[反映](https://en.wikipedia.org/wiki/Reflection_(computer_programming))のビルトイン機能はありません。 。実行時に標準の方法でデータの種類を取得することはできません。 –

+1

また、GCCとClangを使用すると、特定の警告を簡単にエラーにすることができます。または* all *警告をエラーにして、特定の警告のエラーを無効にします。 –

+0

フォーマット指定子は型のためのものではありません。例えば。 '%o'と'%x'はどちらも 'unsigned int'をとります。 '%e'、'%f'、 '%g'はすべて' double'をとります。 '%d'、'%i'、 '%c'はすべて' int'をとります。だからあなたは(一般的に)議論からそれらを推論することができないのです。 – melpomene

答えて

2

データ型からの除外フォーマット指定子?

なし

メルポメネが述べたように:

は、「書式指定子だけのタイプのためではありません例:%o%x両方がunsigned intを取る;すべてはdoubleを取る%e%f%g; %d%i%cすべてがintを取ることが理由です。あなたは(一般的に)議論からそれらを推論することはできません。

このような機能が存在する場合、unsiged int%oまたは%xに推計しますか?等々 。 。 。場合によっては警告または問題を出すべきかどうかについて


、あなたは鋳造がでどのように機能するか、そしてそれが何かを許可するかどうかを意味をなすしたときに考えなければなりません。 GCCでは、あなたはもちろん、エラー(S)と(S)警告扱うことができます:

-Werror 
Make all warnings into errors. 

-Werror= 
Make the specified warning into an error. The specifier for a warning is appended; for example -Werror=switch turns the warnings controlled by -Wswitch into errors. This switch takes a negative form, to be used to negate -Werror for specific warnings; for example -Wno-error=switch makes -Wswitch warnings not be errors, even when -Werror is in effect. 

The warning message for each controllable warning includes the option that controls the warning. That option can then be used with -Werror= and -Wno-error= as described above. (Printing of the option in the warning message can be disabled using the -fno-diagnostics-show-option flag.) 

Note that specifying -Werror=foo automatically implies -Wfoo. However, -Wno-error=foo does not imply anything. 

をあなたはhereを読むことができるよう。

1

データ型に対してプログラムでフォーマット指定子を推測することはできますか? _Genericの使用しての種類の選択セットに制限が

printf()ではない簡単にも直接

、まだ...

はい、。

これは種々の方法を行い、大きなdificultyと*printf()とともに使用、まだ私はこの例では、個々のフォーマット指定子を指定せずに、データを印刷するための類似のアプローチを見つけることができる:
Formatted print without the need to specify type matching specifiers using _Generic
注:このコードは、符号化孔を有します私がパッチを当てた後に持っているポインタの数学に関して - 投稿されていないが。ストリングとx

GPrintf("Name is ", GP(name), " is ", GP(dob), GP_eol); 

キーマクロGP(x) 2つの部分に展開有することによってテキストにタイプを変換するために使用されるコードの選択を操縦する_Generic(parameter)を使用することでした。その後、GPrintf()は引数を解釈します。
これは@Michaël Royのコメントに似ていますが、C++ではなくCにとどまっています。

+0

'_Generic'に関する不具合報告があります。一部の解釈は実装に残されますation。それはまた、例えば以下のように動作しない。 'size_t'は標準型の' typedef'ですが、別の変換型指定子を使います。 – Olaf

+0

@Olaf "typedef"である "size_t"については、 '_Generic'のレベルで扱うことができます。例えば。最上位レベルは 'unsigned、unsigned、long、unsigned long long'と' default'を使用します。 'default'は' size_t'を持つ第2レベルの_Generic_を使います。これは常に 'z'を提供するとは限りませんが、コードが重要であるかどうかを区別することができます。 IOWは_comparable_指定子を持つことができます。 – chux

+0

6.5.1.1p2を読んでください: "...同じジェネリックセレクションの2つの汎用的な関連は互換性のある型を指定しません..." - 別名 'typedef unsigned int size_t;'は 'unsigned int'と互換性がありますか?レポートを読む。より多くの問題があります。明示的にclangとgccを同一ではない実装としてリストしています。これとは別に、存在しない問題に対するあまりにも難解なことです。 Cは静的に型指定され、すべての型はコンパイル時に認識され、印刷は通常、既知の型を使用します。特殊な出力は、追加の注意が必要です(リンクされた例が示すように)。問題を探している解決策。 – Olaf

関連する問題