C言語なら俺に聞け 154

■ このスレッドは過去ログ倉庫に格納されています
2020/01/14(火) 19:32:30.16ID:SgRnb4BR0
!extend:checked:vvvvv:1000:512
(新スレ立ての際上記コマンドを2行書き込んでください)
C言語の話題のみ取り扱います C++の話題はC++スレへ
質問には最低限の情報(ソース/コンパイラ/OS)を付ける
数行で収まらないソースは以下を適当に使ってURLを晒す
https://paiza.io/
https://ideone.com/
http://codepad.org/

C11
http://www.open-std.org/jtc1/sc22/WG14/www/docs/n1570.pdf

C99
http://www.open-std.org/jtc1/sc22/WG14/www/docs/n1256.pdf
http://kikakurui.com/x3/X3010-2003-01.html

C FAQ 日本語訳
http://www.kouno.jp/home/c_faq/

JPCERT C コーディングスタンダード
https://www.jpcert.or.jp/sc-rules/

※前スレ
C言語なら俺に聞け 153
https://mevius.5ch.net/test/read.cgi/tech/1566050562/
VIPQ2_EXTDAT: checked:vvvvv:1000:512:: EXT was configured
2020/03/28(土) 22:37:27.60ID:dAv8M8Ft0
ちなみに &printf も同じ値だね。
ちなみに関数ポインタ変数 p を使った場合、&p は変数p 自体のアドレスになったけど、p も *p も関数自体のアドレスで同じ値になる。
ちょっとややこしいかも。
432デフォルトの名無しさん (ワッチョイ 368c-bMls)
垢版 |
2020/03/29(日) 04:08:50.01ID:qP8s4jbH0
メモリを[アドレス](データ)で表すと
int ***A;は
[Aアドレス](アドレス1) -> [アドレス1](アドレス2) -> [アドレス2](アドレス3)
-> [アドレス3](int データ)
を指していることかな。
2020/03/29(日) 06:29:54.31ID:MtcIJfqw0
int (*fp)(void); /* fp: 引数なし, intを返す関数を指すポインタ */
と定義された関数ポインタ fp を経由して関数を呼び出す際に、
fp() でも (*fp)() でも同じ意味だよ、と規格で決めた結果として、
ならば (**fp) も (***fp) も…同じだよね、てことになったのかな。

アドレス演算子の方も
fp = some_func;
fp = &some_func;
どちらの書き方でも fp 経由で同じ関数を呼び出せる、という点で合理的か。
他の解釈をしても意味ないし。

おかげで
fp = &**&***&some_func;
などと書くこともできる。これは無意味で過剰な一般化の類にも思えるけど。
fp = &&some_func;
とは書けない模様。
この辺の挙動はコンパイラによって違うのかも。
2020/03/29(日) 07:46:51.93ID:oQB7eLYm0
sizeof fp //ok
sizeof *fp //error

fp = &some_func; //ok
fp = &fp; //error
435デフォルトの名無しさん (ワイーワ2 FF1a-nBi6)
垢版 |
2020/03/29(日) 16:07:52.64ID:7B/pleQ/F
int a = (*&*&*&*&*&*&*&f)();
こんなんもありか?
2020/03/29(日) 16:10:44.92ID:7+eNyT920
++--++--++--++--a;
2020/03/30(月) 06:39:21.96ID:VZ0aGjef0
>>436
Cだとコンパイルエラーだね。
最右の--で増やされた値に左隣の++を作用させられない。

C++だと動作する。
「前置の++/--演算子が左辺値を返す」だっけ。
2020/03/30(月) 07:50:54.17ID:VZ0aGjef0
誤: 最右の--で増やされた値
正: 最右の--で減らされた値

増減を間違えたわ。
439デフォルトの名無しさん (ワッチョイ 1b8c-xyAh)
垢版 |
2020/04/01(水) 21:03:42.40ID:HmSenNAk0
そろそろ変数名、関数名にUTF-8を使えるようにしてもいいと思う。
多分楽しくなるよ。
2020/04/01(水) 22:34:39.51ID:9N+QUSAtM
void ぴゅう太(void) {
漢字();
漢字();
鉄矢();
鉄矢();
}
2020/04/02(木) 06:56:27.27ID:RbNpa6BP0
全角空白やアラビア語などを駆使したioccc作品が楽しみだな
2020/04/02(木) 07:54:18.84ID:iOa0mW0IM
古老おらんか
cmakeてのはいつ頃流行ったシロモノなんだ?
2020/04/02(木) 08:47:09.83ID:CP0ku5lBM
よく知らんが5年前には普通に使ってた
2020/04/02(木) 12:01:47.47ID:yWN/hb600
i286時代の16bitC言語ってfarポインタ経由でも64KBごとにしか連続メモリアクセスできなかったんでしょうか?
2020/04/02(木) 12:17:36.01ID:cFIQnebc0
透過的にはアクセスは出来なかったと思う
2020/04/02(木) 12:24:50.02ID:8fgIRfU4M
連続アクセスをどのレベルで言ってるのかによるけどHugeポインタ使えば見かけ上は連続アクセスできる
ただしかなり遅い
2020/04/02(木) 12:29:05.08ID:72QlOXRc0
FARポインタって値としてはリニアアドレスで、メモリアクセス時に内部的にセグメントとオフセットに分けてるだけじゃなかっけ?
ポインタを ++ しながらメモリアクセスして 64KB 越えても問題無いんじゃね?
memcpy みたいのが内部的に rep 使った lods や stos を使ってるなら、ライブラリとして 64KB 単位に区切ってるんじゃないのかな。
2020/04/02(木) 12:31:00.60ID:72QlOXRc0
あれ、おれの言ってるのって hugeポインタだっけ?
2020/04/02(木) 12:39:01.60ID:cFIQnebc0
もう使ってないし、使いたくもないし、思い出したくもないw
2020/04/02(木) 12:40:53.46ID:RoFHMWcRd
組み込み小規模は今でもメモリモデルやらFARポインタやらがある
2020/04/02(木) 13:48:38.35ID:RbNpa6BP0
i80286のバグを利用してリアルモードでありながら1MB超のメモリを使うなんてテクあったな
2020/04/02(木) 14:07:43.96ID:yWN/hb600
>>446
連続アクセスはポインタを ++ でインクリメントしながらループするレベルで言っています
Hugeポインタというものもあったんですね、知りませんでした
これを使うとポインタを ++ する度にセグメントレジスタを更新するので遅いが64KB以上のアクセスができるって事ですよね

farポインタはポインタを ++ してもセグメントレジスタは更新されず、早いけど64KB以上のアクセスはできないって事でしょうか?
あれ、もしそうなら例えば0x0EFFF0を指すfarポインタで ++ しながらメモリアクセスした場合
16バイト以上は0xE0000に戻ってしまい0x0F0000以降のメモリにアクセスできないって事ですか?
2020/04/02(木) 17:09:56.05ID:0sikvQpW0
「正規化マクロ」なんてのもあった記憶がある。
オフセット部の上位ビットをセグメント部に移して、
オフセット部の値を 0-15 に制限する。

適当なタイミングで「正規化」することで
64KBを越える範囲を連続的にアクセスできるようになる。
いわゆる「透過的」ではないけれど。
454デフォルトの名無しさん (エムゾネ FF43-8H9x)
垢版 |
2020/04/02(木) 18:29:53.16ID:4X8ewqwSF
>>442
90年代前半?
455デフォルトの名無しさん (エムゾネ FF43-8H9x)
垢版 |
2020/04/02(木) 18:32:26.76ID:4X8ewqwSF
>>452
もちろんそのセグメントで扱えるブロックの範囲の先頭に戻る
そういうときはセグメントレジスタの方の値を増やさないと無理
456デフォルトの名無しさん (エムゾネ FF43-8H9x)
垢版 |
2020/04/02(木) 18:35:21.60ID:4X8ewqwSF
>>452
誤解されそうなので補足だけど
>0x0EFFF0を指すfarポインタで ++ しながらメモリアクセスした場合
セグメントレジスタ 0x0EFFF
ポインタ 0x000F
なら 0x0EFFFF にアクセス出来るし
セグメントレジスタ 0x0EFFF
ポインタ 0x0010
なら 0x0F0000 にアクセス出来る
2020/04/02(木) 18:58:03.66ID:SCUy7Ffk0
>>456 >>453
ああなるほど、セグメントレジスタは16倍してオフセットに加算されるんですね
勘違いして認識していました、ありがとうございます
そうなるとfarポインタでも基本的には64KBまでならそのままアクセス可能そうですね
2020/04/02(木) 21:31:59.26ID:F2YXKB2C0
>>446
>Hugeポインタ
速度ペナリティも高かったし、なによりもバグっているとの報告がちらほら…
2020/04/02(木) 21:33:11.59ID:F2YXKB2C0
>>447
オフセットがあふれてもセグメント部分はインクリメントしない、したがって 64 KB を超えて連続アクセスはできない
2020/04/02(木) 21:33:30.14ID:F2YXKB2C0
>>448
huge はバグっていた
2020/04/02(木) 21:41:01.11ID:ZwiItXECM
30年前にタイムスリップしたかと思った
2020/04/02(木) 22:01:10.37ID:KR7Qg6ip0
Hugeがバグってた?
本当?
2020/04/03(金) 01:16:56.77ID:rS9EMaRY0
>>457
16ビットと一言で言ってるけど、x86の場合リアルモードとプロテクトモードでセグメントの扱いは全く異なるから注意
16倍して足すだけなのは前者のとき(DOSとか)
Windows3.1は後者
2020/04/03(金) 07:13:39.26ID:sD1svSjIM
>>462
そういう処理系があったって話でしょ
まあ処理系のバグだーって言う奴の99%は自分のコードがバグってるんだけどな(俺調べ)
2020/04/03(金) 07:42:16.55ID:smM7aeLk0
そうそう
どうせコードがバグってるのをコンパイラのバグだと騒いでるんだと思って聞いてみた
2020/04/03(金) 08:17:02.15ID:y4LIlYUL0
まあQZは思い込みが激しいし話半分に聞いておけばいいな
2020/04/03(金) 20:17:25.73ID:W+mHIVdh0
>>462
中島信行氏の記事にそういうのがありました

>>464
huge ポインタがあったのはたしか MS だけだったかと
2020/04/03(金) 20:59:00.91ID:15ER3YJX0
>>464
条件が成立してるはずなのにどうしても走らないコードがあり、コンパイラの最適化のバグで処理が消えたと思い最適化のスイッチをいろいろいじり、
それでもだめでコンパイラ自体のバグを疑い吐かせたアセンブラソースに処理コードが吐かれてないことを確認して、
ほれ見たことかコンパイラが悪い!と報告を上げた後でコメントの */ が抜けてることを発見した俺には敵うまい。
2020/04/04(土) 00:47:19.29ID:qMa2xGJ10
私はいくつかコンパイラのバグを見つけたけどね
見つけた時は発生する最小形にしてから報告

コンパイラのバグだとさわぐヤツの99%は自分のバグ
ってのは同意
2020/04/04(土) 00:50:16.07ID:igeAmwMLM
>>467
> huge ポインタがあったのはたしか MS だけだったかと
Turbo Cですらサポートされてるんだが…
https://www.drdobbs.com/using-large-arrays-in-turbo-c/184402289
2020/04/04(土) 00:55:46.93ID:yxoY6Q+20
Internal Error って言うのを見たことはある
2020/04/04(土) 08:44:49.54ID:glhU6EPt0
99%もそんなアホいるのか?
コンパイラのバグを疑った場合まず最小の再現コード作るだろ
で、バグレポに条件と現象を書くわけだが
自分が悪い場合はそこで必ず気付くことになる
2020/04/04(土) 09:28:47.06ID:oeIO06yp0
>コンパイラのバグだとさわぐ
× こういう風に書いたのですがxxのコンパイラなら問題ないのにxxxの方だと誤作が(ry
〇 xxxつかったら動かねぇ!!ソースに間違いは無い!!クソコンパイラ!!謝罪と賠(ry
2020/04/04(土) 10:12:08.70ID:o3XzX6/PM
>>472
> コンパイラのバグを疑った場合まず最小の再現コード作るだろ
> で、バグレポに条件と現象を書くわけだが
そんなこともせずに騒いでる奴が多いって話だろ
2020/04/04(土) 12:47:58.45ID:yxoY6Q+20
今は分からないが、20年くらい昔だと
あまりにも複雑なソースを食わせると時々発狂してたな
476デフォルトの名無しさん (ワッチョイ 23ad-Ujw5)
垢版 |
2020/04/04(土) 13:15:20.63ID:SI4lxjMM0
>>468
負けた。君に勝ちを譲ろう。
2020/04/04(土) 13:15:46.68ID:nDualHANd
30年前くらいじゃないか?
あまりにも複雑なソースを書くのが悪い
っていう時代

今でもあまりに複雑なソースは悪
別の意味で
2020/04/04(土) 13:29:50.17ID:3Wwr2fKwM
10年くらい前でもマクロのネストが多いとかでInternalエラー吐く処理系はあったよ
本来ちゃんとエラーチェックして適切なエラーメッセージ出すべきなんだろうけどほとんどありえないような状況にどこまで対応すべきかって話はなかなか難しいものがある
まあそれと処理系のバグとは別の話だが
2020/04/04(土) 14:50:27.38ID:glhU6EPt0
>>477
そんなん、やろうとしていること次第だろ
複雑になっちまうものはそうするしかない
意地悪しているわけでもないコードをけなすのは
自分の品位を損なう愚行だ
2020/04/04(土) 15:13:09.29ID:KrNZzm/nM
>>479
複雑って言うのはスパゲティコードというより循環的複雑度みたいな話だと思うよ
複雑度が上がるなら適切に関数化するとかで避けるとか
2020/04/04(土) 15:16:24.42ID:glhU6EPt0
なんか全然、噛み合ってないね
2020/04/04(土) 15:55:02.64ID:nDualHANd
「あまりに複雑な」
って時点で悪

やろうとしてることが複雑でも
記述を複雑にする必要は無い
2020/04/04(土) 19:49:17.44ID:glhU6EPt0
なんだ、主観論か
484デフォルトの名無しさん (ブーイモ MM6b-eRVI)
垢版 |
2020/04/05(日) 00:53:15.82ID:8lfN7LOTM
cでコンパイラがゲロる複雑に成るって三項演算子をネストするくらいだろ
c++はテンプレートでわりあい簡単に混乱を引き出せるけどCのメタ構築機能はゴミみたいなもんだし
2020/04/05(日) 05:06:11.76ID:UG8XDQGA0
3項がどう結合するかを理解してないやつがオレ文法と違うって騒ぐのは
駅前で不特定多数を叱りつけている危ないオヤジと同じ
2020/04/05(日) 07:26:24.26ID:c+nOX//s0
人間にとっての複雑とコンパイラにとっての複雑化はまったく違う

演算子のネストなんて3項じゃなきゃ普通にやってることで
コンパイラにとっては普通のこと

3項演算子の結合は特殊なので
人間にとっては複雑なのは間違いないけど
2020/04/05(日) 07:31:27.17ID:c+nOX//s0
3項演算子の優先度は
良くある演算子の優先度表を見るだけじゃ仕様がわからない

>>485もその辺を理解してるかどうか
2020/04/05(日) 09:05:29.09ID:1wSwWGx9M
>>487
> 3項演算子の優先度は
> 良くある演算子の優先度表を見るだけじゃ仕様がわからない
意味不明、普通にわかるだろ
https://ja.cppreference.com/w/c/language/operator_precedence
2020/04/05(日) 09:20:09.55ID:nuvXPfKL0
>>488
その表でもわざわざ欄外に注記している通り、演算子の順位だけを見ても分からないということだろう
490デフォルトの名無しさん (JP 0H93-3bw/)
垢版 |
2020/04/05(日) 11:43:40.11ID:pjXS/HuIH
4Dエンジン
ttp://x0000.net/topic.aspx?id=3677-0

ある強力なFor関数
ttp://x0000.net/topic.aspx?id=3630-0

SQLライブラリ
ttp://x0000.net/topic.aspx?id=3675-0

matrixのライブラリ
ttp://x0000.net/topic.aspx?id=3711-0
2020/04/05(日) 13:47:36.92ID:h0VsrhLiM
C/C++仕様が違うんだよね三項演算子
2020/04/05(日) 14:48:53.25ID:28SxhHQj0
三項演算子は優先順位よりも結合性の方がわからなくなる
493デフォルトの名無しさん (ワイーワ2 FF93-8H9x)
垢版 |
2020/04/05(日) 14:56:50.54ID:P07lI1PFF
A ? B : C;
A ? B ? D : E : C ? F : G;
(A ? B ? D : E : C) ? F : G;
A ? B ? D : E : (C ? F : G);
2020/04/05(日) 15:03:25.55ID:1D4UZmeK0
>>492
私は
A1 ? B1 : A2 ? B2 : A3 ? B3 : C3
みたいにお気楽に後ろに後ろに結合するのがいいです
2020/04/05(日) 15:03:37.61ID:bk3bMB+g0
コンパイラにとって複雑というのは、構文木が深くなる、とどのつまり項の多い長い文なんじゃない?
昔のコンピュータはメモリが足りなかったから深い木は扱えなかったってことでしょ。
496デフォルトの名無しさん (ワイーワ2 FF93-8H9x)
垢版 |
2020/04/05(日) 15:58:31.05ID:PRah2HwrF
>>494
人間には右につなげる方が見やすいのかも知れないが
コンパイラ的にあいまいさが無いのは左(内側?)に入れていく方だと思う

Pythonのはさらに結合の優先度が判りにくい気がする(慣れてないだけかも知れない)
2020/04/05(日) 19:35:26.18ID:Wi/hOB0pd
>>494
それは時と場合によるのでは?
2020/04/05(日) 19:36:57.26ID:Wi/hOB0pd
>>493
改行を工夫すると見やすくなる
2020/04/07(火) 02:00:59.45ID:52b5Xapk0
>>498
例えばどんな感じですか?
2020/04/07(火) 07:11:26.19ID:Aukj6IXD0
? を if と同じように改行 & インデントすればいい

A ?
    B ? D : E :
    C ? F : G;

A
    ? B ? D : E
    : C ? F : G;
2020/04/07(火) 07:15:13.75ID:Aukj6IXD0
A ?
. . B ? D : E :
. . C ? F : G;

A
. . ? B ? D : E
. . : C ? F : G;
2020/04/07(火) 07:20:31.07ID:Aukj6IXD0
>>494の場合は

A1 ? B1 :
A2 ? B2 :
A3 ? B3 : C3

A1 ? B1
: A2 ? B2
: A3 ? B3
: C3
2020/04/07(火) 07:39:02.54ID:XHj6H39W0
なぜ素直にif文を使わないんだ
2020/04/07(火) 08:25:22.73ID:Aukj6IXD0
当然 if や switch caseやテーブルと使い分ける
? : が適した場合に使う
2020/04/07(火) 08:57:58.17ID:w7aWdcFI0
某「省略の美学」とか言うのを売りにしてる言語に憧れてるんだろ。
506デフォルトの名無しさん (ワッチョイ 23ad-Ujw5)
垢版 |
2020/04/07(火) 12:46:52.50ID:rrWnJIGn0
この世には括弧というものがあってだな・・・
2020/04/07(火) 12:55:18.38ID:PCdj22SH0
三項演算子で処理を書くな
ただの代入にわざわざif文を使うな
2020/04/07(火) 17:39:24.91ID:2Qz700Q3d
代入の右辺だけ書いただけ
処理でこんな書き方をするのは特殊な場合(競技とか)
509デフォルトの名無しさん (ワッチョイ 23ad-Ujw5)
垢版 |
2020/04/07(火) 23:16:28.11ID:rrWnJIGn0
Kotlinは思い切って三項演算子なくした代わりにifを式にしちゃったよ。
他の言語からのパクリだとは思うが、val a = if (x == y) b else c のような書き方ができる。
2020/04/08(水) 00:50:21.46ID:UIymVg5v0
>>509
lisp とか haskell とか、関数型全般はそうやりますよね…
2020/04/08(水) 02:14:53.71ID:VV8vD69L0
>>509
その記述
int a = x == y ? b : c;
に比べて何かメリットあるの?
2020/04/08(水) 03:26:20.58ID:5a3Kp3Hv0
>>511
ダメと言われている三項演算子を使ってません!と言えることかなw

一つあるとしたら、ネストさせたときに if ... else if ... else if ... else とできることか。
式の中に文のような表現が入る気持ち悪さがあるから、三項演算子の方がまだましな気もするが。
2020/04/08(水) 08:02:03.15ID:VV8vD69L0
ダメといわれている?
初耳

else if は >>494>>502 が同じ事をやってて
こっちの方が見やすいと思う
2020/04/08(水) 09:37:01.78ID:5a3Kp3Hv0
>>513
どこかのコーディング規約や一部の教条主義者の間で言われてるみたいだよ。(>>512前段はそれを揶揄したつもり。)
俺自身は三項演算子は分かりやすさを損なわない範囲で使うのは大好きだし、>>502の前者の書き方はよく使う。
2020/04/08(水) 12:55:24.71ID:NPiFCq9kd
gotoダメとか3項演算子ダメとか
2020/04/08(水) 15:40:20.61ID:s9R4Lcv40
関数呼び出しするのに、引数ではなくグローバル変数でやり取りする奴見たことある
ナイフ一本持ってジャングルの中を探検する気分になれた
2020/04/08(水) 16:05:35.74ID:b5xs9aHC0
gotoは例外処理とか使いどころもあるのに、大人はみんなダメと言う
2020/04/08(水) 16:06:38.12ID:b5xs9aHC0
>>516
スタック節約とかのバッドノウハウとしてはよく見る
2020/04/08(水) 16:12:43.67ID:zy2o7H5P0
>>516
シングルトンのクラスだと思えばそんなに変じゃないんじゃね?
2020/04/08(水) 16:36:56.26ID:do2Qazkj0
>>519
シングルトンならグローバル構造体にして関数を介して読むべきだな
2020/04/08(水) 17:43:28.57ID:VkTQCF2n0
>>516
よくやります。君もやりたまえ。
2020/04/08(水) 18:06:51.24ID:VV8vD69L0
関数仕様(プロトタイプ)を変えたくないとか
関数をたすさん経由するので変更が多いとか
少しでもパフォーマンスをあげたいとか
少しでもリソースをけちりたいとか

理由はいろいろとある
綺麗さよりもそういった事が重要であれば使うこともある
2020/04/08(水) 18:20:05.30ID:do2Qazkj0
パフォーマンス改善の仕事してるけどパフォーマンスのためにグローバル変数使うとか聞いたことないわ
2020/04/08(水) 19:27:06.81ID:vCaQPcU3M
井の中の蛙宣言しても意味無くない?
2020/04/08(水) 20:24:48.12ID:zy2o7H5P0
>>520
別に構造体にする必要は無いじゃん。
しいて言えば、引数でたらい回しにするときこそ構造体が便利で、そういうやり方になるとシングルトンというより this を明示的にやり取りする普通のオブジェクトみたいなもんじゃね。
グローバル変数でシングルトン的に実装するなら、グローバル変数を全部 static にしてソース内にスコープを絞る感じじゃね。
2020/04/08(水) 20:33:22.56ID:zy2o7H5P0
>>523
キャッシュにヒットしやすい配置に並べやすいとか、
引数渡しでは必要なスタックに引数を積み上げるコストを節約できるとか、
戻り値を複数貰いたい場合に余計なポインタや構造体を使う必要が無いとか、
「どの程度」はともかくいろいろありそうだけど。
2020/04/08(水) 21:53:33.85ID:3lkMRJ1l0
>>516
組み込みだとよくあるよ。その方がデバッグしやすいんだと。
2020/04/09(木) 02:17:55.56ID:qzPRDrss0
ICEのメモリダンプでリアルタイムに状態の変化を追跡するのに変数のアドレスがスタックを動き回られては確認しづらいので
グローバル変数で寿命を永続化してアドレスマップを固定アドレス化することはよくある
2020/04/09(木) 07:57:04.28ID:bPuB4yJ40
errnoの悪口?
2020/04/09(木) 11:01:14.49ID:/KG6GbYC0
C言語10年ぐらいやってるけどいまだにエラー機構の正解が見えない
errno使おうかと思ってた時期もあるけど、けっきょく構造体使ってエラーハンドリングしちゃう
2020/04/09(木) 11:29:30.64ID:DMgYiRAM0
>>530
グローバル変数とlongjmp
■ このスレッドは過去ログ倉庫に格納されています
5ちゃんねるの広告が気に入らない場合は、こちらをクリックしてください。