C言語なら俺に聞け 145
■ このスレッドは過去ログ倉庫に格納されています
>>296-298 , >>300 , >>305 お前らがどう思おうとマイクロソフトはセキュリティ強化版って言ってるから #define a(b) c##b##d というマクロでcdを出力したいのですが a()を呼び出すとエラーになります 解決策ありますでしょうか? >>314 俺のところはエラー出ないみたい。環境によるのかな。 コンパイラのバージョンを示せば詳しい人が現れるかも。 コンパイラーのエラーが出ないという意見をきいて 試してみたら別のところ―がエラーになっていたということでした。 そして自分が悪質なコンパイラーに騙されていたことに気づきました。 Cのエラーはエラーの発生個所を教えてくれるけど原因個所は教えてくれない おそらく警告とエラーを混同していると思われ > warning C4003: マクロ 'a' に指定された実引数の数が少なすぎます。 関数型マクロの使用時、カッコの内側が空の場合に、 「引数が指定されていない」と解釈して警告を出すか、 「1個の引数(内容はヌルストリング)が指定されている」と解釈するか、 そういう問題みたいね。 >>292 >int8_tは内部がcharかもしれないけど便宜上charではありません。 普通はsigned charだな。当たり前。「charかもしれない」なんてこともありえない。 そういう一般仕様から外れるコンパイラの使用を強制させられたことあるの? cout << typeid(__int8).name(); //char 符号なし64ビット整数を64ビット右シフトすると 0にならないでそのままの時や変な別の値になるときがあるんですけど コンパイラーのバグですか? >>329 もしかしてですが、 悪質なコンパイラに騙されているのでは? http://fast-uploader.com/file/7076138459666/ 2つのファイルが無いと再現できなかったのでソースファイルを アップロードしました コンパイルしてなぜ0にならないのか教えてください。 >>329 a >> b で、bの値がaの型のビット数「以上」のときは未定義動作、 に該当するから、コンパイラのバグではない。…と思う。 本当は規格の引用をすべきなんだが、どなたか頼む。 コンパイラーは gcc version 7.3.0 (Rev1, Built by MSYS2 project) で試しました。 悪質なコンパイラーに騙されているのかもしれませんね。 ファイル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; } この二つのファイルをコンパイルして実行してみてください。 よろしくお願いします。 その昔、CPUのバグで16bitレジスタを32bitシフトすると0にならないとかいうのなかったっけ これからは64ビットのシフト使ってるコードは全てバグの温床になるな。 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. >>337 フォローありがとう。この部分ですわ。 6.5.7 Bitwise shift operators ビットシフト演算子 の項。 もしも右オペランドの値が負、または汎整数拡張後の左オペランドの(ビット)幅より 大きいか等しい場合、振る舞いは未定義である。 と言った感じかな。 promoted left operand の部分が「汎整数拡張後の左オペランド」で 合ってるのか自信ないけど。 64bit 符号なしを、64bit シフトするって、そもそも無意味だろ 元のビットが残っていない。 全部のビットが変わっている! 意味があるのは、63bit まで >>339 0になってくれれば余計な分岐やら演算やらを省けるかもしれないだろ 1010 XOR 1010 ---- 0000 n は任意のビットで、n XOR n で、全ビット0にできる >>342 そんなん全ビット読まなきゃいけないじゃん n and 030 とかで任意ビットのonはわからないか? 定数リテラルにullって使ってなくてもだいじょうぶなんだっけ? >>343 xor は少サイクルなのが利点ですね。 今じゃ乗除演算さえワンサイクルの時代に何アホな話してんだ? アセンブラについてはどうしても自分でアセンブリ言語で書かねばならない事態に陥らない限り書くことはないだろうなあ。 >>354 そうそう、printf デバッグでは力不足でもう否が応でも gdb に行くのを逃げ回っているのと同じです 割り込みん中でprintf使って暴走してデバッグが出来なかった思い出。 俺はシグナルハンドラの中でログ出力しようとして FILE * 経由で fprintf() 等で出力したら そのライブラリの中でデッドロックしてハマった。 kill -ABRT で core dump させて gdb で core ファイルと共に読ませてようやっと停止箇所がわかった。 gdbマスターしてからprintデバッグバカにしてたけど printデバッグ自動化してからprintデバッグ信者になった 無論レアケースデバッグはgdb使うけどね printf() をデバッグで使う時はバッファリングを考慮していないとハマる事がある。 それと stdout と stderr と両方に出る可能性がある場合にその順序が食い違う可能性もある。 シグナルハンドラ内やマルチスレッドプログラムで使ってうまく行かない事もある。 その辺を全て考慮するならいいだろうが、しかし、それなら初めからログファイルに出力される ように作った方が良いような気もする。 printデバッグなら専用モジュール作るべきだな 俺は時刻、関数名、コンテキストIDを付けて 標準出力かファイルにはかせてる >>361 setvbuf忘れなければ済む話だよパパ >>363 そだねー >>364 本当にそれだけで大丈夫かね? この頃のライブラリは多分マルチスレッドでもちゃんと動くように内部でロック掛けている部分があると 思うんだけどね、例えばシグナルハンドラの中でそのロックを掛けている最中にまたシグナルが来て 同じシグナルハンドラに入ると同じロックを掛けようとしてデッドロックするなんてことが起こり得ると 思うんだが。(まあその程度のことでデッドロックしてしまうこと自体がバグかも知れんが。それ以前に シグナルハンドラの中でprintf()は使うなって話でもあるか…)。 >>365 ロケールがCならprintfだってスレッドセーフだしぎりぎりシグナルセーフだよパパ 世の中には完全なCライブラリを実装していないタイニーなマシン用のサブセットだってあるんだよ坊や。 それはCじゃないから、このスレで話し合っても無駄では。 30年以上前だったかな、あるメーカーのプリンタファーム開発用Cコンパイラが配列要素上限が255だった 当時アスキーネットでこれを聞いたvoid氏が呆れていたようだ。 インストラクションに8ビットまでの即値を組み込めるなら、その制限によって(そのような最適化が必要なプロセッサにとって)強烈な最適化をかけられるから、アリやナシやと問われればアリのような感がある。 Cライクって言っときゃいいのにCと名乗ってしまうから イチャモンつけたいヤツの標的になる 本場ドイツ直輸入ポークソーセージを買ったら魚肉ソーセージだったような感じですね。 つまり詐欺です。 >>369 それ言ったらバッファリングの話題もCの話にならないだろぉオヤジィ 何が正当な教義かについて議論したければ、上級者スレでやってね こういう掲示板で宗教対決を規制したら過疎化するんじゃないだろか。 >>366 マルチスレッド版のライブラリーがあるかと 行出力中にスレッドが切り替わらない >>374 なお初代K&Rにはライブラリーの仕様は含まれない。 WhiteSmithとかはprintfが実装されてない 5Vシングルエンドがそのままコネクタに出てるアレか アレを基板に直付けするアフォが多くて頭クラクラした for(i=0;i<10;i++) scanf("%d",&num[i]) で入力した変数がiに入ってしまうことがあるのですがなぜですか? アルゴリズムによってはdo whileの方が素直なときがある。まれだが。マクロを本当の関数っぽく使うのにdo while (0)使うハックがある。まれだが。 コンパイラによってはdo whileの方が速いコード出す。まれだが。 >>370 プリンタっつーてもピンキリだからなぁ レシートプリンタとかならその程度で充分かもしれん >>385 んなこたーない whileのほうが使用頻度は高いけど 本質的に後判定なロジックはそんなに珍しくもない do〜whileは、必ず一回は処理してくれるから便利。 繰り返し対象処理が実行される条件がブレるから気をつけないといけないけどね do{continue;}while(false); で無限ループになるのウケる。 391 error: undeclared symbol 'false' こんな書き方たまにする do{ ・・・ 条件 break; ・・・ 条件 break; ・・・ 条件 continue; ・・・ 条件 break; ・・・ 条件 continue; ・・・ }while(0); >>387 一応汎用のレーザープリンターなんだ 30年って一寸行き過ぎだな 95が出てきた頃だから、20年前か >>394 GOTOを怖がるな。 俺は反GOTO教は抜けた。 まぁ乱用しようとも思わんけど。 >>392 文脈で察してくれ。 boolはいったことだし。 B 判定 A B 判定 A B … みたいに do { } while () のブロックの途中に飛び込んで開始するようなのが悩ましい goto ENTER; do { A(); ENTER: B(); } while(条件); 出口が複数は可だけどエントリーポイントが変なとこにあるのは読みにくいからやめたほうがいい。 この例の場合はB Aの無限ループにして、Bのあとの条件で脱出するのが定石。 for(;;) { B(); if (条件) break; A(); }; こんな感じですか。 やっぱり頭から入っていくほうが読みやすいし… 処理内容がそうならそういうことなんだろうが、 見ていて気持ちが悪くなるロジックだな、すまん エントリーポイントが変なとこって、mainだって1行目にはまずならないしな 実装されることなく廃止になったキーワードにentryつーのがあって そいつがおそらくは1行目に entry main; とか持ってこれるようにするつもりだったのかもな >>397 昔の BASIC を思い起こさせる goto の使い方だなw gotoは禁止はしないが、異常系の終了処理にジャンプするパターンだけ許容だな。 コンストラクター/デストラクターのような機構があれば 異常時の後始末は割と楽に書けるっすね >>408 volatileをつけ忘れて最適化で暴走するなんてよくあること。 >>395 1995年頃でLBPだと16bitから32bit CPUに移行する頃だから配列サイズが最大255なんて言うのはさすがに見たことないわ ちなみにうちはSH-2+独自モニタからR3000+VxWorksへの移行期だった コンパイラもチップベンダーかOSベンダーのものを使ってた gotoを後始末以外の使い方して変な所に飛ばしたりするから禁止って言われるんだよな。 ■ このスレッドは過去ログ倉庫に格納されています
read.cgi ver 07.5.4 2024/05/19 Walang Kapalit ★ | Donguri System Team 5ちゃんねる