2016-09-05 7 views
2

私はいくつかのレガシーコードを通じてつもりだと私は作者(もはや存在しないが)-(-n)だけでなくnを書いたのはなぜ二重否定の理由は何ですか - ( - n)?

char n = 65; 
char str[1024]; 
sprintf(str, "%d", -(-n)); 

のようなものを見てきましたか? --nで十分でしょうか?

+7

、-N二重否定のプリデクリメントinteadあろう。 – Alex

+2

明示的な型変換を行うことなく、 'n'を' int'型の値に変換する方法です。 – Peter

+1

@Peter:引数のために 'char'が' int'に変換されるので、無用です。二重否定はUBを(一部ではないが)ターゲットに呼び出すことができる。 – Olaf

答えて

13

注意すべき最初のものは--nが実際n 1だけ減少し、charタイプと、新しい値に評価することです。だから、-(-n)とはまったく違うことをします。 コードを変更しないでください!

-nnの単項否定を実行しによりさらに否定が元の値に設定Cのルール型プロモーションではなく保持タイプintともタイプintのexpresionあります。

だから-(-n)は、実際には無操作しないが、この場合には、それはintタイプnを変換するのにしばしばある書き込み+nの詳細な方法です。

私は誤ったリファクタリングから自分自身を守り、フォーマット指定子%dで引数の型が不一致であると心配していたと思われます。

しかし、この特に場合、それは問題ではありません:sprintfが自動的intcharタイプを推進していきますので、それは

sprintf(str, "%d", n);

を書くために完全に安全だもの大きさを小さくすることを検討してください。 strバッファーが「実際の」コードであれば、より安全なsnprintfバリアントの使用を検討してください。 (二重否定は、符号付き整数型のオーバーフローを得ることができるので、注意して使用しないことを最終的な発言ノートとして。)

+3

'int'と' char'のビット幅が同じで問題が発生します。例えば、 2の補数 'INT_MIN'は、ネゲートされたときにUBを呼び出します。 'char'がすべての値>' INT_MAX'に対して符号なしであれば同様です。私はこの構成に何の利益も見ません。 – Olaf

関連する問題