C言語なら俺に聞け 145

■ このスレッドは過去ログ倉庫に格納されています
2018/02/19(月) 22:13:58.98ID:9/te2eSJ0
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言語なら俺に聞け 144
https://mevius.5ch.net/test/read.cgi/tech/1514025223/

次スレを立てる時は本文の1行目に以下を追加して下さい
!extend:on:vvvvv:1000:512
VIPQ2_EXTDAT: default:vvvvv:1000:512:----: EXT was configured
2018/03/07(水) 17:13:49.35ID:ylRgY7un0
vz?
2018/03/07(水) 17:14:24.12ID:GwlIl+h20
MS-DOSが動作していれば使えるはず
2018/03/07(水) 17:17:05.15ID:ylRgY7un0
dispelしなきゃ無理じゃね?w
2018/03/07(水) 17:21:00.28ID:XsGIcGwmp
secureじゃねーだろ。
暗号化だってされてねーんだからw
safetyくらいな感じじゃね?
306デフォルトの名無しさん (アウアウカー Sabb-g3Yl)
垢版 |
2018/03/07(水) 17:25:48.32ID:Rf3JBuAda
DOSのシステムコール(なんて言うんだっけ?DOSコール?忘れた)だけを呼び出しているプログラムならハードウェアが違っても動く。

しかしMS-DOSはCUIしかサボートしてないのでグラフィックスは使えない。

当時のプログラムはみんな勝手にOS無視してグラフィックスのVRAMに直接アクセスして絵を出していた。
すると当然他の機種に持っていくと意図した通りに動かない。
307デフォルトの名無しさん (アウアウエー Sa9f-wl/W)
垢版 |
2018/03/07(水) 17:26:24.22ID:L+d1J7Rsa
int21
2018/03/07(水) 17:27:45.62ID:rG21M89G0
INT 21H なら ファンクションコールだったかの
2018/03/07(水) 17:28:50.29ID:GwlIl+h20
伝統のCALL 5
2018/03/07(水) 17:29:37.78ID:ylRgY7un0
DOSCALLS.DLLてのもあったなあw
311デフォルトの名無しさん (アウアウエー Sa9f-wl/W)
垢版 |
2018/03/07(水) 17:55:21.18ID:L+d1J7Rsa
CP/M か
0066 とかもあったっけ
2018/03/07(水) 19:19:15.79ID:Zw7oeE4wM
>>296-298, >>300, >>305
お前らがどう思おうとマイクロソフトはセキュリティ強化版って言ってるから
2018/03/07(水) 21:48:34.17ID:mAtFjoDLa
super man
2018/03/08(木) 05:46:05.86ID:Eav/q7cG0
#define a(b) c##b##d
というマクロでcdを出力したいのですが
a()を呼び出すとエラーになります
解決策ありますでしょうか?
2018/03/08(木) 07:45:03.75ID:/HWAGXcB0
>>314 俺のところはエラー出ないみたい。環境によるのかな。
コンパイラのバージョンを示せば詳しい人が現れるかも。
2018/03/08(木) 07:52:57.57ID:Eav/q7cG0
ありがとうございます。
解決しました。
2018/03/08(木) 08:09:34.78ID:Ed7uI0ohM
どう解決したか書くのが礼儀ってもんだ。
2018/03/08(木) 08:29:41.94ID:Eav/q7cG0
コンパイラーのエラーが出ないという意見をきいて
試してみたら別のところ―がエラーになっていたということでした。
そして自分が悪質なコンパイラーに騙されていたことに気づきました。
2018/03/08(木) 09:10:26.22ID:lHBKoGy1p
エラーの文章くらい読めよ。
320デフォルトの名無しさん (アウウィフ FF1f-0aB1)
垢版 |
2018/03/08(木) 10:10:36.36ID:ue18PqKiF
Cのエラーはエラーの発生個所を教えてくれるけど原因個所は教えてくれない
2018/03/08(木) 10:25:51.65ID:0lNTHbnP0
おそらく警告とエラーを混同していると思われ

> warning C4003: マクロ 'a' に指定された実引数の数が少なすぎます。
2018/03/08(木) 17:10:32.81ID:/HWAGXcB0
関数型マクロの使用時、カッコの内側が空の場合に、
「引数が指定されていない」と解釈して警告を出すか、
「1個の引数(内容はヌルストリング)が指定されている」と解釈するか、
そういう問題みたいね。
2018/03/08(木) 23:40:10.76ID:nwTnwFPU0
>>292
>int8_tは内部がcharかもしれないけど便宜上charではありません。

普通はsigned charだな。当たり前。「charかもしれない」なんてこともありえない。
2018/03/09(金) 00:58:31.73ID:U4YZHGfl0
そういう一般仕様から外れるコンパイラの使用を強制させられたことあるの?
2018/03/09(金) 06:39:09.84ID:K2/JY7Cc0
cout << typeid(__int8).name(); //char
2018/03/09(金) 10:59:36.49ID:rlkWp7/Ip
誰だよCの話題に別言語持ち出してんの。
2018/03/09(金) 12:10:45.59ID:WqdE+VIZM
いやらCね
328デフォルトの名無しさん (アウアウカー Sa7b-vvOV)
垢版 |
2018/03/09(金) 12:13:57.64ID:LlK9d7kba
頭おかC
2018/03/09(金) 16:36:39.04ID:AbBnYUJz0
符号なし64ビット整数を64ビット右シフトすると
0にならないでそのままの時や変な別の値になるときがあるんですけど
コンパイラーのバグですか?
2018/03/09(金) 17:10:28.27ID:aCtfd81Na
>>329
もしかしてですが、
悪質なコンパイラに騙されているのでは?
2018/03/09(金) 17:10:41.68ID:AbBnYUJz0
http://fast-uploader.com/file/7076138459666/
2つのファイルが無いと再現できなかったのでソースファイルを
アップロードしました
コンパイルしてなぜ0にならないのか教えてください。
2018/03/09(金) 17:11:34.80ID:er4JdT2d0
>>329
a >> b で、bの値がaの型のビット数「以上」のときは未定義動作、
に該当するから、コンパイラのバグではない。…と思う。

本当は規格の引用をすべきなんだが、どなたか頼む。
333デフォルトの名無しさん (ワッチョイ 7361-0aB1)
垢版 |
2018/03/09(金) 17:12:19.58ID:AbBnYUJz0
コンパイラーは
gcc version 7.3.0 (Rev1, Built by MSYS2 project)
で試しました。
悪質なコンパイラーに騙されているのかもしれませんね。
2018/03/09(金) 17:25:01.13ID:AbBnYUJz0
ファイル1
#include<stdio.h>
#include<stdint.h>
uint64_t f(uint8_t a,uint64_t b){
printf("%llx\n", b>>(64-a));
return b>>64-a;}
void e(uint8_t a){ f(0,0x8318318318318318);}
void g(uint8_t a){ f(a,0x8318318318318318);}
ファイル2
#include<stdint.h>
uint64_t f(uint8_t a,uint64_t b);
void g(uint8_t a);
void e(uint8_t a);
int main(void) {
g(0);
e(0);
return 0;
}
この二つのファイルをコンパイルして実行してみてください。
よろしくお願いします。
2018/03/09(金) 17:27:15.48ID:K2/JY7Cc0
その昔、CPUのバグで16bitレジスタを32bitシフトすると0にならないとかいうのなかったっけ
2018/03/09(金) 17:45:47.23ID:AbBnYUJz0
これからは64ビットのシフト使ってるコードは全てバグの温床になるな。
2018/03/09(金) 18:10:27.57ID:Z9n7UPH0M
C11の6.5.7の3より。
If the value of the right operand is negative or is greater than or equal to the width of the promoted left operand, the behavior is undefined.
2018/03/09(金) 20:12:23.00ID:er4JdT2d0
>>337 フォローありがとう。この部分ですわ。
6.5.7 Bitwise shift operators ビットシフト演算子 の項。

もしも右オペランドの値が負、または汎整数拡張後の左オペランドの(ビット)幅より
大きいか等しい場合、振る舞いは未定義である。

と言った感じかな。
promoted left operand の部分が「汎整数拡張後の左オペランド」で
合ってるのか自信ないけど。
2018/03/09(金) 21:17:55.13ID:ysNVe5/v0
64bit 符号なしを、64bit シフトするって、そもそも無意味だろ

元のビットが残っていない。
全部のビットが変わっている!

意味があるのは、63bit まで
340デフォルトの名無しさん
垢版 |
2018/03/09(金) 22:22:53.87
>>339
0になってくれれば余計な分岐やら演算やらを省けるかもしれないだろ
2018/03/09(金) 22:57:22.97ID:dpc+cSNT0
0クリアする最適な方法なの?
2018/03/09(金) 23:23:40.83ID:ysNVe5/v0
1010 XOR
1010
----
0000

n は任意のビットで、n XOR n で、全ビット0にできる
343デフォルトの名無しさん
垢版 |
2018/03/09(金) 23:25:22.45
>>342
そんなん全ビット読まなきゃいけないじゃん
2018/03/09(金) 23:29:26.36ID:9IZd/e860
n and 030 とかで任意ビットのonはわからないか?
2018/03/09(金) 23:47:39.35ID:U4YZHGfl0
>0クリア
つ ゼロレジスタ
2018/03/10(土) 00:03:47.54ID:a2p+alti0
1 bit づつじわじわシフトするなら何とかなるんだけどな。
https://paiza.io/projects/D9KFwMa77ifp6AOgAaO2PQ
2018/03/10(土) 05:55:47.17ID:jel/5KgH0
定数リテラルにullって使ってなくてもだいじょうぶなんだっけ?
2018/03/10(土) 12:12:18.84ID:Z1L9sOVC0
>>343
xor は少サイクルなのが利点ですね。
2018/03/10(土) 13:08:59.94ID:qojMr6PP0
アセンブリコードの0にする方法はxorやのう
2018/03/10(土) 13:24:16.81ID:+HpaswK40
CPU依存すぎる
2018/03/10(土) 13:47:45.54ID:f+B2oLbA0
Z80時代の爺だろ、放置してやれ
2018/03/10(土) 14:18:47.85ID:J/EnQN8G0
パチンコ屋さん
2018/03/10(土) 15:25:43.76ID:ps/htySn0
今じゃ乗除演算さえワンサイクルの時代に何アホな話してんだ?
354デフォルトの名無しさん (アウアウカー Sa7b-joIP)
垢版 |
2018/03/10(土) 16:20:41.72ID:HvD6qwC3a
アセンブラについてはどうしても自分でアセンブリ言語で書かねばならない事態に陥らない限り書くことはないだろうなあ。
2018/03/10(土) 16:50:09.76ID:+Ww908Qw0
>>354
そうそう、printf デバッグでは力不足でもう否が応でも gdb に行くのを逃げ回っているのと同じです
356デフォルトの名無しさん (ワッチョイ 0b9f-RK0z)
垢版 |
2018/03/10(土) 17:18:49.50ID:a2p+alti0
gdb は普通に使うなあ。
357デフォルトの名無しさん (アウウィフ FF1f-0aB1)
垢版 |
2018/03/10(土) 17:35:13.89ID:5pXC+BOTF
printfなめたらいかん
2018/03/10(土) 17:41:43.93ID:ps/htySn0
割り込みん中でprintf使って暴走してデバッグが出来なかった思い出。
2018/03/10(土) 18:10:52.64ID:a2p+alti0
俺はシグナルハンドラの中でログ出力しようとして FILE * 経由で fprintf() 等で出力したら
そのライブラリの中でデッドロックしてハマった。 kill -ABRT で core dump させて gdb
で core ファイルと共に読ませてようやっと停止箇所がわかった。
2018/03/10(土) 20:11:43.97ID:fNi+2/6HM
gdbマスターしてからprintデバッグバカにしてたけど
printデバッグ自動化してからprintデバッグ信者になった
無論レアケースデバッグはgdb使うけどね
2018/03/11(日) 01:20:23.17ID:ry5KQfC80
printf() をデバッグで使う時はバッファリングを考慮していないとハマる事がある。
それと stdout と stderr と両方に出る可能性がある場合にその順序が食い違う可能性もある。
シグナルハンドラ内やマルチスレッドプログラムで使ってうまく行かない事もある。

その辺を全て考慮するならいいだろうが、しかし、それなら初めからログファイルに出力される
ように作った方が良いような気もする。
2018/03/11(日) 02:00:44.19ID:22CnVBlaM
printデバッグなら専用モジュール作るべきだな
俺は時刻、関数名、コンテキストIDを付けて
標準出力かファイルにはかせてる
363デフォルトの名無しさん (ワッチョイ 8f23-0aB1)
垢版 |
2018/03/11(日) 09:19:44.59ID:zWe+i43K0
そこまでするならsyslog
2018/03/11(日) 10:20:33.73ID:szqHStkk0
>>361
setvbuf忘れなければ済む話だよパパ
365デフォルトの名無しさん (ワッチョイ 0b9f-uQtz)
垢版 |
2018/03/11(日) 14:10:54.85ID:ry5KQfC80
>>363
そだねー

>>364
本当にそれだけで大丈夫かね?

この頃のライブラリは多分マルチスレッドでもちゃんと動くように内部でロック掛けている部分があると
思うんだけどね、例えばシグナルハンドラの中でそのロックを掛けている最中にまたシグナルが来て
同じシグナルハンドラに入ると同じロックを掛けようとしてデッドロックするなんてことが起こり得ると
思うんだが。(まあその程度のことでデッドロックしてしまうこと自体がバグかも知れんが。それ以前に
シグナルハンドラの中でprintf()は使うなって話でもあるか…)。
2018/03/11(日) 15:06:05.16ID:szqHStkk0
>>365
ロケールがCならprintfだってスレッドセーフだしぎりぎりシグナルセーフだよパパ
2018/03/11(日) 15:33:10.91ID:UYIqocxw0
世の中には完全なCライブラリを実装していないタイニーなマシン用のサブセットだってあるんだよ坊や。
368デフォルトの名無しさん (ワッチョイ 23b3-lJdD)
垢版 |
2018/03/11(日) 16:08:45.67ID:sEfAJdP70
それはCじゃないから、このスレで話し合っても無駄では。
2018/03/11(日) 16:12:01.01ID:UYIqocxw0
Cは言語仕様であって、ライブラリ仕様は別枠だろ?
2018/03/11(日) 16:46:35.93ID:iUqzSqql0
30年以上前だったかな、あるメーカーのプリンタファーム開発用Cコンパイラが配列要素上限が255だった
当時アスキーネットでこれを聞いたvoid氏が呆れていたようだ。
371デフォルトの名無しさん (ワッチョイ 23b3-lJdD)
垢版 |
2018/03/11(日) 17:10:10.38ID:sEfAJdP70
インストラクションに8ビットまでの即値を組み込めるなら、その制限によって(そのような最適化が必要なプロセッサにとって)強烈な最適化をかけられるから、アリやナシやと問われればアリのような感がある。
2018/03/11(日) 17:20:27.39ID:Dtt3qpb50
Cライクって言っときゃいいのにCと名乗ってしまうから
イチャモンつけたいヤツの標的になる
373デフォルトの名無しさん (ワッチョイ 23b3-lJdD)
垢版 |
2018/03/11(日) 17:33:57.41ID:sEfAJdP70
本場ドイツ直輸入ポークソーセージを買ったら魚肉ソーセージだったような感じですね。
つまり詐欺です。
2018/03/11(日) 17:36:14.99ID:szqHStkk0
>>369
それ言ったらバッファリングの話題もCの話にならないだろぉオヤジィ
2018/03/11(日) 17:37:59.08ID:iUqzSqql0
何が正当な教義かについて議論したければ、上級者スレでやってね
376デフォルトの名無しさん (ワッチョイ 23b3-lJdD)
垢版 |
2018/03/11(日) 18:04:00.35ID:sEfAJdP70
こういう掲示板で宗教対決を規制したら過疎化するんじゃないだろか。
377デフォルトの名無しさん
垢版 |
2018/03/11(日) 18:26:39.19
>>370
まるでUvaみたいな制限だな(藁
2018/03/11(日) 18:45:46.67ID:QedwXA9H0
>>366
マルチスレッド版のライブラリーがあるかと
行出力中にスレッドが切り替わらない
2018/03/11(日) 18:48:04.93ID:QedwXA9H0
>>374
なお初代K&Rにはライブラリーの仕様は含まれない。
WhiteSmithとかはprintfが実装されてない
2018/03/11(日) 20:24:48.92ID:1mhcZmSWa
>>372
セントロニクス
2018/03/11(日) 21:13:40.31ID:Dtt3qpb50
5Vシングルエンドがそのままコネクタに出てるアレか
アレを基板に直付けするアフォが多くて頭クラクラした
382デフォルトの名無しさん (ワッチョイ 6ac6-lLam)
垢版 |
2018/03/11(日) 23:26:14.78ID:3FTmPjnp0
for(i=0;i<10;i++)
scanf("%d",&num[i])

で入力した変数がiに入ってしまうことがあるのですがなぜですか?
2018/03/11(日) 23:59:04.31ID:Sn9rQkOCM
numのサイズが10ないとか。
2018/03/12(月) 00:02:45.79ID:9wDOvV2B0
ソース全部晒せ
2018/03/12(月) 07:51:36.03ID:6B2Hj+UH0
do whileはいらない子?
2018/03/12(月) 08:04:24.78ID:uoSNo/WDM
アルゴリズムによってはdo whileの方が素直なときがある。まれだが。マクロを本当の関数っぽく使うのにdo while (0)使うハックがある。まれだが。
コンパイラによってはdo whileの方が速いコード出す。まれだが。
2018/03/12(月) 08:36:16.07ID:SpziwmuNM
>>370
プリンタっつーてもピンキリだからなぁ
レシートプリンタとかならその程度で充分かもしれん
2018/03/12(月) 09:25:52.84ID:kO6Vn+sG0
>>385
んなこたーない
whileのほうが使用頻度は高いけど
本質的に後判定なロジックはそんなに珍しくもない
2018/03/12(月) 09:30:32.07ID:Cd8AY8RG0
do〜whileは、必ず一回は処理してくれるから便利。
2018/03/12(月) 09:31:53.62ID:kO6Vn+sG0
繰り返し対象処理が実行される条件がブレるから気をつけないといけないけどね
2018/03/12(月) 10:16:52.94ID:Igle62xq0
do{continue;}while(false); で無限ループになるのウケる。
2018/03/12(月) 10:19:34.77ID:kO6Vn+sG0
391 error: undeclared symbol 'false'
2018/03/12(月) 10:42:19.80ID:wLVR4ID4a
>>389
女に見習わせたいな
394デフォルトの名無しさん (ワッチョイ 8f23-0aB1)
垢版 |
2018/03/12(月) 12:03:54.32ID:A4+OWJSs0
こんな書き方たまにする

do{
・・・
条件
break;
・・・
条件
break;
・・・
条件
continue;
・・・
条件
break;
・・・
条件
continue;
・・・
}while(0);
2018/03/12(月) 12:10:22.44ID:rLGzoMUT0
>>387
一応汎用のレーザープリンターなんだ
30年って一寸行き過ぎだな
95が出てきた頃だから、20年前か
2018/03/12(月) 12:11:48.84ID:Igle62xq0
>>394
GOTOを怖がるな。
俺は反GOTO教は抜けた。
まぁ乱用しようとも思わんけど。

>>392
文脈で察してくれ。
boolはいったことだし。
2018/03/12(月) 15:52:19.83ID:bCYSOHOV0
B 判定 A B 判定 A B … みたいに
do { } while () のブロックの途中に飛び込んで開始するようなのが悩ましい

goto ENTER;
do {
 A();
ENTER:
 B();
} while(条件);
2018/03/12(月) 17:04:49.51ID:Ro63JAiYH
出口が複数は可だけどエントリーポイントが変なとこにあるのは読みにくいからやめたほうがいい。
この例の場合はB Aの無限ループにして、Bのあとの条件で脱出するのが定石。
2018/03/12(月) 17:15:21.51ID:bCYSOHOV0
for(;;) {
 B();
 if (条件) break;
 A();
};
こんな感じですか。
やっぱり頭から入っていくほうが読みやすいし…
2018/03/12(月) 17:24:28.52ID:rLGzoMUT0
処理内容がそうならそういうことなんだろうが、
見ていて気持ちが悪くなるロジックだな、すまん
2018/03/12(月) 17:31:42.39ID:kO6Vn+sG0
エントリーポイントが変なとこって、mainだって1行目にはまずならないしな
実装されることなく廃止になったキーワードにentryつーのがあって
そいつがおそらくは1行目に
entry main;
とか持ってこれるようにするつもりだったのかもな
■ このスレッドは過去ログ倉庫に格納されています