アカウント名:
パスワード:
if((...) && (uid = 0)){}これを 0 == uid 以外だめってことにすればいいんじゃない?というか eq とか subst とかいうマクロにしたらどうだい?
その手のミスはコンパイラが検知してくれるので、わざわざおかしな書き方を強制するのは本末転倒。左辺に定数を書かせるやり方は、そもそも比較の両辺が変数だった場合に適用できないし。
本家には wait4: 'if ((options == (__WCLONE|__WALL)) && (current->uid = 0)) ...' と書いてますね。なんで日本語だと本文に無いんだか。
で、これだと代入が括弧で囲まれてるから警告出ないと。確かにcurrent.uid == 0だと括弧要らないですが、&&の右辺だと括弧入れるコーディングスタイルの人も多いから厄介ですね。それもあって単なるうっかりミスかもしれないとも言われてました(ちゃんと議論追ってないので良く分からないですが)。
この場合だと二重括弧じゃないと警告出すようにすれば良いとも思うのですが、しかし色々と一貫性を考えてみるとそもそもCの構文が悪い気もする。
> 色々と一貫性を考えてみるとそもそもCの構文が悪い気もする。
つまり、「=」が代入で「==」が比較というCの定義が悪いということだと思います。あるいは、代入を構文ではなく演算子だとしてしまったために、式が書けるあらゆるところで代入が可能になってしまったのが悪いということでしょうか。
たしかに、Cの基本設計(代入は演算子なので、本来、ifの条件式の中でも代入ができるべき)を認めた上で、かつ今回のような問題を防ぐには、小手先の小細工になってしまうし、一貫性を失って奇妙なことになる(カッコで囲まれていたら警告を出さないとか)と思います。
だったら、Cでその定義は今更変えられないから、新しい言語を作って、BASICみたいに「=」は演算子じゃないことにしてしまうか、FORTRANみたいに比較は「eq」とかを使うようにするか、Pascalみたいに代入は「:=」で比較は「=」にするか、でも、C式の定義がC以外にも広く使われてるし、かえって混乱を招くかもしれません。
代入が式であることが問題で、記号はどうでもいいでしょう。あとは条件式がbool以外を取れることが問題です。言語仕様を変えなくても、コンパイラがそれをチェックして警告を出すことは可能だと思いますよ。
しかし、この場合、条件の値が0なので、もしそんな警告が存在すれば、NULLやFALSEを0と定義している場合、全て警告を出されてしまうので、到底実用的じゃないと思う。
言ってるように、括弧が付こうがなんだろうが、代入を式として評価しない方がいいし、それで十分だろう。
括弧付き代入の警告も、既存のプログラムだと警告が結構でるかもしれないと思ったので、その点はあえて目をつぶりました。警告はOFFにできるしね。
Cじゃない別の言語を作る話なら、bool以外取らないという解決策の方が個人的には良いと思う。代入式がそこら中に書けるのはシンプルで分かりやすいコードにできる方法だと思う。代入1つのために中抜けループとか作りたくないし。
> Cじゃない別の言語を作る話なら、bool以外取らないという解決策の方が個人的には良いと思う。
if ((count < MAX) || (f = true)) {のようにbool型の変数へ代入してしまうバグは残る(作れる)ので万全とはいいにくい気が
# さらにboolの比較演算子をなくせばいいかな?# if (!is_not_support() != false) みたいなコードもなくなるし
> 代入1つのために中抜けループとか作りたくないし。
while (c = getchar() ; c != EOF) {…}のようにかければ、ほかは「代入文」でもなんとかなりません?
個人的には「代入文」(もしくは代入演算子の戻りをvoid)にして整理したほうが学習コストもバグ発生率も下げられるのでは?と思ってます
#2476303 ですが、私が考えてたのは、代入が式として扱えることには何ら異論はなくて、exp1 && exp2は正当なのに、if exp hogeと書けないのが変だなということでした。
&&のような条件演算子だって短絡評価を使えば実際if文に近い使い方はできるのに、左右に表れる式に括弧をつけなくても問題ない。ただし、自主的に括弧をつける人も多い。一方、if文だと式に必ず括弧をつける必要がある。で、代入文を括弧で囲わないと式として扱わない(警告を出す)ようにした場合、if文だとコード上は二重の括弧で囲われた形になるのに対し
&&のあとだとどうだとか、二重括弧がどうだとか、こんなにややこしいことを考えないといけないのなら、いっそのこと、代入を式として扱えることを放棄してしまったほうが単純明快なのではと思います。
ひとつで複数の副作用を起こせる文(あるいは式)が存在する、ということそのものが、人間のすなおな理解を超えているんじゃないかと思うのです。(べつに、人間の理解力を超えていると言いたいわけじゃないです。疲れてるときとか、うっかりとか、そういうときにミスが出やすいポイントだと思います)。というわけで私は #2476486の意見に賛成です。
いろいろ組み合わせると、マクロの方が鬱陶しいからなぁ。 定数を先に書くのはよくやるけど、両方変数だったら、運を天に任せる感じ。
規約やマクロを用意したって、悪意があれば使わないでしょう。「警告を尊重せよ」で充分な気がする。
-Werror ですねわかります
#include >iso646.h>
そういうおまじないは、鼻から出てきた悪魔には通用しない。どれだけ完璧なエラーチェックだとしても、未定義の悪魔はエラーチェックごと消し去ってしまう。
マクロ展開やインライン展開の裏側では、プログラマの与り知らない所で、大量のデットコードが生成され、それを元に最適化がかけられるという。世にも恐ろしい儀式が行われている。儀式の最中にコンパイラのオプティマイザが悪魔召喚の危険性を感知し警告したとしても、殆どのプログラマはその警告を理解することが出来ない。なぜならそのコードはプログラマーが書いたものではないからだ。そして悪魔そのものを召喚したデットコードは最適化の過程で削除される。その結果、極めて妥当に見えて、まるで動いている様に見える、そしてその実、全く意味のないコードが発生する。
まあなんだ、少なくともデッドコードと未定義挙動は全く別の警告が出るものだと思うがそれくらいはプログラマが理解しましょうよ
どんなトラウマがあったのかは知りませんが、デッドストリップ最適化も未定義動作もゴッチャにして恐れてる時点で…。
(1) そもそもifの中で代入なんかするのが悪い、代入したけりゃ分けて書け、というコーディングスタイルを確立する。(2) それと同時に、ifの中で代入していたら、(カッコで囲っていようとも)問答無用でコンパイラが警告あるいはエラーを出すようにする。
定数を先に書くのはありだけど、比較をうっかり(あるいは、うっかりに見せかけて故意に)代入にしてしまうのを防ぎたいという話なのだから、定数を先に書くのをうっかり忘れるのを防止する手段を講じない限り意味がない。
定数を先に書くのをうっかり忘れて、しかも比較と代入を間違えるって、単に比較と代入を間違えるよりは、少なくない?でも、間違えてた箇所みたときは、故意??って思ったけど
より多くのコメントがこの議論にあるかもしれませんが、JavaScriptが有効ではない環境を使用している場合、クラシックなコメントシステム(D1)に設定を変更する必要があります。
※ただしPHPを除く -- あるAdmin
C が悪い(フレームのもと) (スコア:0, 興味深い)
if((...) && (uid = 0)){}
これを 0 == uid 以外だめってことにすればいいんじゃない?
というか eq とか subst とかいうマクロにしたらどうだい?
Re:C が悪い(フレームのもと) (スコア:1)
その手のミスはコンパイラが検知してくれるので、わざわざおかしな書き方を強制するのは本末転倒。左辺に定数を書かせるやり方は、そもそも比較の両辺が変数だった場合に適用できないし。
Re:C が悪い(フレームのもと) (スコア:1)
本家には wait4: 'if ((options == (__WCLONE|__WALL)) && (current->uid = 0)) ...' と書いてますね。なんで日本語だと本文に無いんだか。
で、これだと代入が括弧で囲まれてるから警告出ないと。確かにcurrent.uid == 0だと括弧要らないですが、&&の右辺だと括弧入れるコーディングスタイルの人も多いから厄介ですね。それもあって単なるうっかりミスかもしれないとも言われてました(ちゃんと議論追ってないので良く分からないですが)。
この場合だと二重括弧じゃないと警告出すようにすれば良いとも思うのですが、しかし色々と一貫性を考えてみるとそもそもCの構文が悪い気もする。
Re: (スコア:0)
> 色々と一貫性を考えてみるとそもそもCの構文が悪い気もする。
つまり、「=」が代入で「==」が比較というCの定義が悪いということだと思います。
あるいは、代入を構文ではなく演算子だとしてしまったために、式が書けるあらゆる
ところで代入が可能になってしまったのが悪いということでしょうか。
たしかに、Cの基本設計(代入は演算子なので、本来、ifの条件式の中でも代入が
できるべき)を認めた上で、かつ今回のような問題を防ぐには、小手先の小細工になって
しまうし、一貫性を失って奇妙なことになる(カッコで囲まれていたら警告を出さないとか)
と思います。
だったら、Cでその定義は今更変えられないから、新しい言語を作って、
BASICみたいに「=」は演算子じゃないことにしてしまうか、
FORTRANみたいに比較は「eq」とかを使うようにするか、
Pascalみたいに代入は「:=」で比較は「=」にするか、
でも、C式の定義がC以外にも広く使われてるし、かえって混乱を招くかもしれません。
Re: (スコア:0)
代入が式であることが問題で、記号はどうでもいいでしょう。
あとは条件式がbool以外を取れることが問題です。
言語仕様を変えなくても、コンパイラがそれをチェックして警告を出すことは可能だと思いますよ。
Re: (スコア:0)
しかし、この場合、条件の値が0なので、もしそんな警告が存在すれば、NULLやFALSEを0と定義している場合、全て警告を出されてしまうので、到底実用的じゃないと思う。
言ってるように、括弧が付こうがなんだろうが、代入を式として評価しない方がいいし、それで十分だろう。
Re: (スコア:0)
括弧付き代入の警告も、既存のプログラムだと警告が結構でるかもしれないと思ったので、
その点はあえて目をつぶりました。警告はOFFにできるしね。
Cじゃない別の言語を作る話なら、bool以外取らないという解決策の方が個人的には良いと思う。
代入式がそこら中に書けるのはシンプルで分かりやすいコードにできる方法だと思う。
代入1つのために中抜けループとか作りたくないし。
Re: (スコア:0)
> Cじゃない別の言語を作る話なら、bool以外取らないという解決策の方が個人的には良いと思う。
if ((count < MAX) || (f = true)) {
のようにbool型の変数へ代入してしまうバグは残る(作れる)ので万全とはいいにくい気が
# さらにboolの比較演算子をなくせばいいかな?
# if (!is_not_support() != false) みたいなコードもなくなるし
> 代入1つのために中抜けループとか作りたくないし。
while (c = getchar() ; c != EOF) {…}
のようにかければ、ほかは「代入文」でもなんとかなりません?
個人的には「代入文」(もしくは代入演算子の戻りをvoid)にして整理したほうが学習コストもバグ発生率も下げられるのでは?と思ってます
Re: (スコア:0)
#2476303 ですが、私が考えてたのは、代入が式として扱えることには何ら異論はなくて、
exp1 && exp2は正当なのに、if exp hogeと書けないのが変だなということでした。
&&のような条件演算子だって短絡評価を使えば実際if文に近い使い方はできるのに、左右に表れる式に括弧をつけなくても問題ない。ただし、自主的に括弧をつける人も多い。
一方、if文だと式に必ず括弧をつける必要がある。
で、代入文を括弧で囲わないと式として扱わない(警告を出す)ようにした場合、if文だとコード上は二重の括弧で囲われた形になるのに対し
Re: (スコア:0)
&&のあとだとどうだとか、二重括弧がどうだとか、
こんなにややこしいことを考えないといけないのなら、
いっそのこと、代入を式として扱えることを放棄してしまったほうが単純明快なのではと思います。
ひとつで複数の副作用を起こせる文(あるいは式)が存在する、ということそのものが、
人間のすなおな理解を超えているんじゃないかと思うのです。
(べつに、人間の理解力を超えていると言いたいわけじゃないです。
疲れてるときとか、うっかりとか、そういうときにミスが出やすいポイントだと思います)。
というわけで私は #2476486の意見に賛成です。
Re: (スコア:0)
いろいろ組み合わせると、マクロの方が鬱陶しいからなぁ。 定数を先に書くのはよくやるけど、両方変数だったら、運を天に任せる感じ。
Re: (スコア:0)
規約やマクロを用意したって、悪意があれば使わないでしょう。
「警告を尊重せよ」で充分な気がする。
Re: (スコア:0)
-Werror ですねわかります
Re: (スコア:0)
#include >iso646.h>
Cのダメなところはそこじゃない (スコア:0)
そういうおまじないは、鼻から出てきた悪魔には通用しない。どれだけ完璧なエラーチェックだとしても、未定義の悪魔はエラーチェックごと消し去ってしまう。
マクロ展開やインライン展開の裏側では、
プログラマの与り知らない所で、大量のデットコードが生成され、それを元に最適化がかけられるという。
世にも恐ろしい儀式が行われている。儀式の最中にコンパイラのオプティマイザが悪魔召喚の危険性を感知し警告したとしても、
殆どのプログラマはその警告を理解することが出来ない。なぜならそのコードはプログラマーが書いたものではないからだ。
そして悪魔そのものを召喚したデットコードは最適化の過程で削除される。
その結果、極めて妥当に見えて、まるで動いている様に見える、そしてその実、全く意味のないコードが発生する。
Re: (スコア:0)
まあなんだ、少なくともデッドコードと未定義挙動は全く別の警告が出るものだと思うが
それくらいはプログラマが理解しましょうよ
Re: (スコア:0)
どんなトラウマがあったのかは知りませんが、デッドストリップ最適化も未定義動作もゴッチャにして恐れてる時点で…。
Re: (スコア:0)
(1) そもそもifの中で代入なんかするのが悪い、代入したけりゃ分けて書け、というコーディングスタイルを確立する。
(2) それと同時に、ifの中で代入していたら、(カッコで囲っていようとも)問答無用でコンパイラが警告あるいはエラーを出すようにする。
定数を先に書くのはありだけど、比較をうっかり(あるいは、うっかりに見せかけて故意に)代入にしてしまうのを
防ぎたいという話なのだから、定数を先に書くのをうっかり忘れるのを防止する手段を講じない限り意味がない。
Re: (スコア:0)
定数を先に書くのをうっかり忘れて、しかも比較と代入を間違えるって、単に比較と代入を間違えるよりは、少なくない?
でも、間違えてた箇所みたときは、故意??って思ったけど