-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
☕ コーディングスタイルで盛り上がった時のコーヒーブランチ ☕ #11
Comments
事例1
の
こう書かれていても、頭の中では一旦考えて、
こう変換している自分が居ます。 例えば冗長という観点で言うと、
これは、
こう書けますが冗長だからと言って下で書く人のほうが少ないのはいうまでもないかと思いますが、
こうしろなんてところもあります(言語によってコメント行だけだとエラーになるのでなにがしかnopな処理を書いたほうがいいかも) 例えば、
これは、
にして、isEmptyはオーバーロード関数にして、引数がintの時は0かそれ以外かでTrue/Falseを返すとか、 で、結論ですが、私は「どっちでもいいんじゃないか」と改めて思いました。
↑これをもう読みにくいと思うのは私から見たらもう「ニュータイプ」なんじゃないかと。 |
Issue 立てありがとうございます!GJ です! |
PR 趣旨から外れた議論が勃発したら、ひとまずはここを避難地にしましょうかね :) |
@kobake さん |
sakura-editor/sakura#200 で上がっていた話題ですが、ヘッダ内での using については個人的には断固拒否なスタンスです。 個人的にはコーディングスタイルは幅広く許容していきたい(と思っている)スタンスですが、ここについては譲れないところであります。ヘッダ内 using を許容するスタンスの人って他で見たことないです。 ※個人プロダクトでは楽するためにやっちゃうことは稀にありますけど。本来は絶対にやりたくない作法です。 |
同じく sakura-editor/sakura#200 でのネタ。
これに同意です。 自分は assert に入れる条件は、原則「静的な論理値」と考えています。 そういう箇所では assert ではなく条件分岐でログ出したり例外出したりその他エラー対策処理を入れるべきところであったかと。 |
C++よくわかってないんで、assertとか、ヘッダの中で usingとかの弊害が身に染みてないですが、「楽できる何か」があるんでしょうねぇ・・・ ただRPの中にあった、
ヘッダがヘッダをインクルードするのは間違いじゃないと思うんですけども、どうなんでしょ。 内容が高度すぎてついていけてませんが。 |
あっちでは既にコメント入っていたので追加コメントは入れませんでしたが、ヘッダがヘッダをインクルードするのは普通。というかむしろ依存関係の意識をヘッダ利用者に負担させない意味で推奨です。 たとえば a.h が b.h に依存していて b.h が c.h に依存しているとき、ヘッダ内ヘッダインクルードの策をとっていない場合、 ちなみに windows.h 自体にもインクルードガード付いてるので、まかり間違って windows.h を2回以上 include してしまっても問題ないです。 |
これについては自分の場合は身になじみすぎて言葉足らずになってしまうことがあり反省。 |
まったくその通りだと思うんですけども
というのを受けて、型の再定義によるコンパイルエラーを避ける方法があるだろうかと考えてみた結果がそうなりました。あくまでも仮定ありきです。 普通に考えてインクルードガードがない世界では、#include <string> する a.h と、#include <string> する b.h の、両方をインクルードする main.cpp において、std::string の定義がダブってしまって、 これをインクルードガードなしで解決するには、main.cpp に #include <string> と #include "a.h" と #include "b.h" を並べ、a.h と b.h から #include <string> を取り除くしかないのではないかと。 google のスタイルガイドに「自己完結型ヘッダー」という言葉がありましたが、こちらはさながら「自己完結型翻訳単位」に当たります。直接・間接を問わずすべての依存ヘッダを一列に並べて把握・管理しようとする姿勢はストイックで嫌いではありませんが、主流派にはなれないでしょう。というか、こんな派閥の存在を知りません。 |
返事 sakura-editor/sakura#200 (comment) をいただけたので、ちょっとここで続けます。 前方宣言を使い、ポインタ型や参照型を関数プロトタイプやメンバ変数の型に使うだけなら型の完全な定義をインクルードする必要がないということでした。それはインクルードガードなしで自己完結型のヘッダを目指す試みですが、それだけでは以下の制限が考えられ、それをスタイルとして集団で許容することができるかどうか。
「(インクルードガードなしでの)自己完結型ヘッダー」を諦めて「自己完結型翻訳単位」を目指すならこれらの制限は乗り越えられますが、茨の道であるのは変わりません。 |
なにやら盛り上がっていたのに今更気付いたなり・・・。 @kobakeさん
完全に同意です。例外投げるコードを書きたかったけどまだ例外の投げ方に関して話できてないので、暫定策としてassertにしてました。assertにしとけば、いつか誰かがおかしい!って言うだろうという確信犯でした。一目で見破るとはさすがです・・・。 |
インクルードガードの話。 正直、いま現在のサクラエディタのインクルードガードはあまり好きじゃありません。 こういうインクルードガードは馴染みがあります。 こういうインクルードガードは良くない気がしています。 後半部分が意味不明なのがよくないと思う理由です。 「インクルードガードとは、意味不明な文字列をソースコードに混入させることである」というのが、 他のプロジェクトやライブラリを気軽に参照できるようにするために、 |
僕は圧倒的に ただ、提供するものが SDK であれば プロダクト単位ではチームメンバーでの合意がとれていれば ちなみに |
参考リンク>インクルードガード | 闇夜のC++ すべてのトピックを網羅する勢いです。これ以外のトピックがあれば知りたい。 |
@KENCHjp さん
頭の中で文意を変換するのは誰でもすることだと思います。 ぼくはBASICでif文を覚えました。 :EXPRが変数なら値があるかどうかの判定です。 ニュータイプなんですかね(^^; |
0 はれっきとした値ですよ。Ruby なら真に評価される値ですよ。 |
話は戻りますが、サクラエディタの定められた形式はこれです。
埋め込むためのマクロが共有されていたはずですが、guidgen.exe のような外部コマンドが必要だったことと、使う機会がそうそうないために、保存はしていませんでした。 |
たぶん、ここなんでしょうね。私はストレスだらけなんすよね。 |
C/C++では整数型変数の値は、CPUのレジスタに格納されます。 C/C++では整数型変数の値がレジスタに直結するので、 javascriptの場合はこんな感じになります。 var a = 0;
if (!a) {
if (a === 0) {
alert('a is zero.'); //a=0はここに来る
} else if (a === '') {
alert('a is blank.'); //a=''はここに来る
} else if (a === null) {
alert('a is null.'); //a=nullはここに来る
} else if (a !== undefined) {
alert('a is NaN.'); //a=NaNはここに来る
} else {
alert('a is undefined.'); //aが未定義はここに来る
}
} else { //else if (a) {
alert('a has value.'); //aに何らかの値が定義されていたらここに来る
} Rubyの実装だと
|
う~む、Rubyでは「if :EXPRの:EXPRが0のときにも条件が成立する」ということがやはり読み取れない。 →たぶん公式マニュアル |
たぶん話まざってますね。
ぼくの脳内変換は前者です。 @KENCHjp さんにしてた指摘は、後者の脳内変換は不要ですよね?ということです。 |
そうかもです。
私も前者です。
そういう考え方もあるは、事例1で書いた通りです。 繰り返しになりますが向こうにも張ったリンクを再掲します。 各言語におけるtrue/falseまとめ
Rubyで0(数値)が真判定されると記載あります。 |
この件については、機械語の話(レジスタ含め)は混ぜないほうが良いと思いますよ。 ゼロを偽、非ゼロを真と脳内変換できる能力はこの話に参加している方々は全員保持していると思っています。 しかしゼロ/非ゼロによる判定はどちらかというとC言語的な世界観であり、それはつまり機械語的な世界観であり、「そういう考え方もある」ことは当然知っているけれども人間的に(というか論理値であることを明示するために)そういう書き方は避けたい人が一定数いる、という文脈として自分は解釈しています。 どの PR だか忘れましたけど、変数 n を2倍にするときに |
@KENCHjp さん
ここが合意とれればぼくは満足です。 |
補足しておくと「 |
完全に別件です。
ぼく日本人なので、文字リテラルがchar型であるとは限らないと思ってます。 auto ch = 'あ'; //これは何型? 「ひらがな」は2バイト文字です。char型では足りません。 ワイドでない文字定数の値は、コンパイル環境のコードページに依存します。 Unicodeの場合、ちょっと状況が違いそうです。 auto ch = L'\U0002000B'; //これは何型? このコードは警告C4066を吐いて意図通りにビルドされません。 auto jo = L'\U0002000B';
auto jostr = L"八\U0002000B島";
auto ret = wcschr(jostr, jo); wcschrの第二引数の型はwchar_tです。 不思議! auto jo2 = L"\U0002000B";
auto jostr = L"八\U0002000B島";
auto ret = wcsstr(jostr, jo2); 現状のvc++ではこうするのがベターなのかな、と思っています。 本題に戻します。
コードポイントが0~127の文字をASCII文字と呼ぶのはご存じだと思います。 どちらで書いても構わないならタイプ数の少ないほうがよいです。 |
コーディングスタイルの Issue 分けていきますかね。 幸い management-forum の他の話題が活発なわけでもないのでコーディングスタイル Issue が乱立しても管理話題が埋もれるとかの問題は当面起こらなそう。 |
たしかに 'あ' は int になりますね |
どっちでも行けますが、ガムシロは入れない派です。 |
セルフつっこみ。
というのは正確ではありませんでした。起源はこんな感じで、使う人がいたということです。guidgen.exe もいりませんでしたね。
|
冒頭を思いっきり「昭和69年」と読みました。 |
auto の利用ポリシーについてはなんとなく意識合わせておいたほうが良いと思いました。 なお昔の C++ であった「iterator みたいな長い型を手書きする必要があった」文化については徹底的にFXXK ですので、そのあたりを auto で綺麗にするのは大賛成です。 なのでこういうのは歓迎。 |
今はガチガチなコーディング規約が有るわけではなさそうで場所によって記述スタイルがまちまちですね。個人的にはヨーダ記法もシステムハンガリアンもかなり好きではないですが信奉者達からするとこういうのは冒涜的な発言で粛清の対象でしょうか…。 .clang-format ファイル用意して統一するようにするのは有りだと思いますが、appveyor とかでチェックするのはどうかなと思います。厳しくした後にプロジェクトが廃れちゃうと(運用ルールを厳しくしたのが原因かはともかく)元も子もないです。 |
ここは多様性を重んじるチームだと信じています。 ですが、敵はバグや実装機能であることをふと一息ついて慮る。。。 |
条件判定してエラー対策を入れるべき箇所では入れるのが正解なので、そういう個所を assert で済ませてしまうのは手抜きですが、戻り値を全くチェックしないよりかはマシなのかもしれません。
あとはエラー処理を律儀に書くのが大変なのでとりあえずは assert を埋め込んでチェックしておいて、エラー処理の記述は後回しにするときとか。。まぁ手抜きと見分けるのが難しいですね。 |
静的なというのはちょっと正確でなかったですね。仕様や前提を宣言する的な用途で使う感覚かなーと。 以下のような assert は割と許容しちゃいますね。
さらに踏み込むと、論理値といいながらここでは生ポインタ突っ込んじゃってますが、こういうのはあえてサボっちゃうことも多いです(サボっているという意識はある)。 |
ですね。有用な制約もありますが、制約の付け方の匙加減は慎重に考えたいです。 以前 @KENCHjp さんがおっしゃられていた
の言葉が自分は好きです。 |
こういうのはアリの認識です。 void f( _In_z_ const char* psz) {
auto len = strlen(psz); //←pszのNULLチェックなし、NUL終端はある前提のコード
} ちゃんと書くなら assert(psz) するのがベターで、 別版でこういうのもあります。 void f( _Out_ int* p) {
*p = 0; //ノーチェックで代入
} DirectWrite関係のライブラリ実装では、こういうのを許容するルールだそうです。 |
そもそも assert って Release ビルド時には抹消されるので速度に影響は出なかったはず(と記憶)。 |
DirectWirteがノーチェックで書込みにいく仕様な件については、 assertがReleaseビルドに含まれないのは正しい認識です。 |
C/C++ 系 LIB はだいたい「速度重視だからしょうがない」の思想ですね。 |
多重ループ内から呼び出しされる場合等の、1回のエラーチェックに掛かる時間が1マイクロ秒以下でも積み重なると問題になるような場合は、正常なパラメータを渡して呼び出すことを前提にする方が良いと思います。エラーチェックするI/FとしないI/Fを分けて用意するのも有りかもしれないですね。 あと外部I/Fではなく内部I/F関数の場合で、範囲外のパラメータを渡す関数の呼び出し方は記述されていないのに関数内で引数のチェックをしていると実質的に無駄な事になってしまいます。 「将来的に誰かが違う呼び出し方をするコードを書くかもしれないのでそれは危ない!」という意見もありそうですが…。 |
sakura-editor/sakura#452 (comment) でちらっと触れた件です。 『エキスパート C プログラミング』のコラムのひとつでした。
この本は主としてコンパイラ(作者)の視点から書かれていて、言語(利用者)の側から書かれた本とはひと味違います。コラムの内容に関しては、これだけでは個人の見解であって、識者の客観的・多面的な評価を待ちたいところです。 C++ だと size() メンバが unsigned 型を返すので、符号なしで統一するという選択肢が視界に入ってくるんですよね。 |
モデラー視点だと、正の数しか取り得ないものは正の数と定義したい。。。 |
もっと進めて整数型をサブクラス化して、単位を型の一部に含める、値の範囲を制限するという考えがありますよね。型でプログラミングするような言語の話だったと思いますが、CLogicInt/CLayoutInt がそういう流れにあるのでしょう。 コラムに関しては、実質的に型が int しかないも同然の C ならではのものかもしれません。 |
clang や gcc のように VC++ でも sanitizer で色々と検出出来ると良いですね。 |
今日読んでいました『Scala 関数型デザイン&プログラミング』という本の pp.284-285 から、contest 関数をリファクタリングする2ステップの例の抜き書きです。 case class Player(name: String, score: Int)
def contest(p1: Player, p2: Player): Unit =
if (p1.score > p2.score)
println(s"${p1.name} is the winner!")
else if (p2.score > p1.score)
println(s"${p2.name} is the winner!")
else
println("It's a draw.")
def winner(p1: Player, p2: Player): Option[Player] =
if (p1.score > p2.score) Some(p1)
else if (p1.score < p2.score) Some(p2)
else None
def contest(p1: Player, p2: Player): Unit = winner(p1, p2) match {
case Some(Player(name, _)) => println(s"$name is the winner!")
case None => println("It's a draw.")
}
def winnerMsg(p: Option[Player]): String = p map {
case Player(name, _) => s"$name is the winner!"
} getOrElse "It's a draw."
def contest(p1: Player, p2: Player): Unit =
println(winnerMsg(winner(p1, p2)))
関数型言語を自分の道具としたことはなく、Scala のコードも、眺めて雰囲気を感じ取るだけですが、副作用を局所化するという考えは理解できます。 それもそのはず、sakura-editor/sakura#452 (comment) や sakura-editor/sakura#509 で示した自分の改良案に共通する特徴だからです。思わぬ援軍を見つけた気持ちでした。 なお、引用部分は第13章の導入であり、その章の眼目ははるかに理解を超えていました。 |
sakura-editor/sakura#650 (comment)
「意図を確認するなんてとんでもない」の真意を書きます。「はぐらかす」という単語に反射的に反発を感じた人も読んでください。 「とんでもない」のは「都合が悪いからそんなことできない」という意味ではありません。「そうする意味・目的・必要がないからそうしない」というだけのことです。 根本的な価値観について確認します。他人に何かを要求すること、他人を動かそうとすることは傲慢な行いです。現代日本には奴隷も主人もなく自由人しかいませんからこれには同意してもらいます。 その上で他人を自分の思い通りにしようとするなら、それなりの準備と企みが求められます。かわいさをアピールしておねだりするのもひとつ。この場に相応しいのは、根拠を集めて理論で武装して理詰めで説得することだと自分は思っています。 「私はこう思う」という感想に対して「私はそうは思わない」は全く問題のない応答です。これが許されないならある人の考えがある人の考えに優先することになりますが、そんなルールは自分は認識していません。 「私はこうすべきだと思う」という修正要求なのであれば、なぜ自分の考えに従うべきであるかの説明があって然るべきだと思います。でなければ「自分がこうだって言うからこうなんだ」という子供らしく傲慢な駄々です。 感想も要求もどちらもあっていいし使い分ければいいんです。しかし体裁が伴っていないのに「これは修正要求であるという意図」だけを確認しても意味がないんです。 完璧にできているかは他者の評価をまたなければいけませんが、自分はコメントの「強度」に応じて真摯に対応しているつもりです。自分の意見が何にも勝るというような対応はしていないつもりです。 |
レビューについての考え方が根本的に違うんですね。 レビューをするときには必ずPRを出すと思うんですが、 考え方は自由ですが、ここに参加する時点である程度傲慢でなければならん気がします。 レビューにコメントを書くってことは、基本的には修正要求です。 とはいえ、PRに対する評価スパンと関係のない感想を書いてしまうこともたまにはあると思います。 どうしたらいい、みたいな具体的なことはゆえんのですが、 |
berryzplus さんの書かれたことは PR の本質的な部分に関しては正しいと思います。その PR が取り込まれるべき理由であるとか、その PR がとる手段の妥当性であるとか、そういうことを PR を出した人は説明する義務があると思います。 しかし自分が先のコメントで想定していたのはコーディングスタイルに関することです(※そういう場所を選んで書きました)。 「こう書いた方が見やすい」というのは主観であり感想です。それに対して「いや私はこの方が見やすいんだ」と返すことが許されるというのが自分の考えです。<追記>なのでいちいちそういう指摘はしません。しかし論拠を思い付いたときに参考情報のつもりで書き連ねたらこれが大失敗でした。</追記> <追記>「インデントが読みにくい」という指摘に対しては「こういう観点でインデントを揃えている」という内容の返答をしました。</追記> PR の本質に関わる部分ではなく、そういうレベルのことについて書きました。 |
了解っす。そんなら問題ないです。
なかなかやれないですけどねw |
Lintやformatterでコードスタイルを強制するのが近年の流行なので自動化できる部分は流れに乗ってみるのもありかもしれませんね 私も個人で書いてるgoとかjavascriptとかはpre-commitフックで強制フォーマット&Lintが通らない限りコミットできないようにしてます。go fmtに関しては設定機能自体が完全に排除されてるので、もはや悩む余地すら無いという徹底ぶり。 |
自分の好きなコードスタイルに皆さんが合わせてくれるという事であれば諸手を挙げて賛成します。 |
beru さんに完全同意です。つまり……(戦争だ!) |
ダメだ。コーヒーブランチになってねぇ・・・w ほぼ同意で、みなさんがぼくに合わせてくれるということなら文句ありません(キリッ |
PR内では、バグじゃなければフォーマットの話はぐっと心の奥底にしまいましょうで、 |
一番コミットからは遠い私がIssue起こすのもはばかったのですが、ひとまず提案。
このチームは固有の「コーディング規約」は規定していない、しないでいいのかなと思っています。
第三者に納品するわけでもなく、参画する人のスキル差は多少あってしかるべきですが、
参画しようという人はそれなりな知識がある人かと思うので、
それよりも開発スピードだったり効率だったりを考えると
ガチガチの「コーディング規約」は足枷にしかならないと思っています。
ですが、スキル差というよりは「ねんき」の差で、
PRの中にコーディングスタイルはこうしたほうがよいああしたほうがよい、
と本来解決せねばならない課題とは別にコーディングスタイルで
PRの議論の半分以上を占めるとそれはそれで本末転倒な気もします。
改めて書くまでもありませんが、PRの中では、
に集中して、「分かりやすさ、再利用のしやすさ、不具合の作りこみにくさ」などで培った経験からくる差で
議論が盛り上がってきたら、いったん冷静になったほうがいいかなと、
張本人な私が言うのもなんですが後から見て思いました。
そうなったら、またはなりかけたら合言葉的なものがあったら、
「あ、そうなのかもしれない、いったん冷静になろう」って思えるかなと。
The text was updated successfully, but these errors were encountered: