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言語なら俺に聞け 146
https://mevius.5ch.net/test/read.cgi/tech/1525031257/
C言語なら俺に聞け 147
■ このスレッドは過去ログ倉庫に格納されています
1デフォルトの名無しさん
2018/08/16(木) 23:36:02.22ID:fOCSKLtw523デフォルトの名無しさん
2018/08/27(月) 12:50:40.87ID:vY3QDx2y だから何でdo while(0)なんて変態コードに固執するんだよ
524デフォルトの名無しさん
2018/08/27(月) 12:51:47.69ID:YYT/vI56525デフォルトの名無しさん
2018/08/27(月) 12:54:54.13ID:woJf6ZC9 元質問者に聞くしかない 「goto は使いたくない」の条件で
526デフォルトの名無しさん
2018/08/27(月) 12:59:44.74ID:ywsjsNTA ブロックというものを中に入ったら出られないものと勘違いしているとか。
最初にforやwhileを覚えちゃって勘違いに繋がったとか。
最初にforやwhileを覚えちゃって勘違いに繋がったとか。
527デフォルトの名無しさん
2018/08/27(月) 13:22:18.19ID:vY3QDx2y 何人たりともforより先に関数のブロックを憶えるのにね
関数のブロックだけが何か特別なものと思い込んでるケースが多い
関数のブロックだけが何か特別なものと思い込んでるケースが多い
528デフォルトの名無しさん
2018/08/27(月) 13:25:30.84ID:Q5lEKL35 goto 便利だけどなぁ。
break するがためのフラグ作って何ブロックも break するとか goto を避けるがためのいびつな if を連続させるとかよりよほど可読性が高い。
もちろん意味を的確に表したフラグやifの構造にできるに越したことはないけどさ。
break するがためのフラグ作って何ブロックも break するとか goto を避けるがためのいびつな if を連続させるとかよりよほど可読性が高い。
もちろん意味を的確に表したフラグやifの構造にできるに越したことはないけどさ。
529デフォルトの名無しさん
2018/08/27(月) 13:28:07.17ID:aXwyVMA/530デフォルトの名無しさん
2018/08/27(月) 13:31:18.13ID:vY3QDx2y ジャクソン法やワーニエ法みたいに
データ構造とプログラム構造を一致させる構造化プログラミング()では
データが損傷していた場合にはプログラム構造を一致させることができない
よって構造化定理を諦めたアプローチをせざるを得ない
こういうのがgotoやlongjmpの出番
データ構造とプログラム構造を一致させる構造化プログラミング()では
データが損傷していた場合にはプログラム構造を一致させることができない
よって構造化定理を諦めたアプローチをせざるを得ない
こういうのがgotoやlongjmpの出番
531デフォルトの名無しさん
2018/08/27(月) 13:32:12.14ID:vY3QDx2y532デフォルトの名無しさん
2018/08/27(月) 13:35:23.06ID:ywsjsNTA ま、Cの場合は適切にgoto使った方が良いだろうな。後から作られた言語では break でラベル指定できるだの例外処理できるだのしてるから使わなくて済むようになってるわけで、それのないCはそれの代わりにgoto利用しちゃった方が分かりやすく書ける。
533デフォルトの名無しさん
2018/08/27(月) 13:41:42.47ID:vY3QDx2y いやCのgotoは制限がキツすぎて
いざという時には役立たず
だからlongjmpがある
いざという時には役立たず
だからlongjmpがある
534デフォルトの名無しさん
2018/08/27(月) 14:22:47.97ID:Q5lEKL35 そんな制限キツかったっけ?
longjump の方がキツいでしょ
longjump の方がキツいでしょ
535デフォルトの名無しさん
2018/08/27(月) 14:23:38.81ID:vY3QDx2y 何がキツいって関数から出らんない
536デフォルトの名無しさん
2018/08/27(月) 14:34:05.72ID:J1p6Vf0T setjump/longjumpは簡易タスクディスパッチャーをC言語だけで実現するためだけにあるのかと思ってたよ。
それ以外の用途はあんまり思い浮かばないなぁ。
それ以外の用途はあんまり思い浮かばないなぁ。
537デフォルトの名無しさん
2018/08/27(月) 14:40:44.92ID:TsaU1TVW 自分で対処不能なエラーが起きたときに、初期化してやり直す時に使ったな
だもんで通常の処理の流れで使うものだとは思わなかった
だもんで通常の処理の流れで使うものだとは思わなかった
538デフォルトの名無しさん
2018/08/27(月) 16:09:02.07ID:vY3QDx2y ディスパッチャとしてはダメダメじゃん
jmp_buf jb;
void sig(int n)
{
longjmp(jb, 1);
}
int main(void)
{
signal(SIGINT, sig);
if (setjmp(jb) == 0) for (;;) ;
else puts("ok");
return 0;
}
俺んとこではokが出ない
おまいらんとこではどんな結果になる?
jmp_buf jb;
void sig(int n)
{
longjmp(jb, 1);
}
int main(void)
{
signal(SIGINT, sig);
if (setjmp(jb) == 0) for (;;) ;
else puts("ok");
return 0;
}
俺んとこではokが出ない
おまいらんとこではどんな結果になる?
539デフォルトの名無しさん
2018/08/27(月) 16:16:45.47ID:J1p6Vf0T 確かsignalとlongjmpは相性悪かったような?
よく覚えてないけど。
よく覚えてないけど。
540デフォルトの名無しさん
2018/08/27(月) 16:27:43.33ID:VuJs8kRo >>538
こちらは Linux (CentOS7)だが、出たよ。
こちらは Linux (CentOS7)だが、出たよ。
541デフォルトの名無しさん
2018/08/27(月) 16:29:13.02ID:VuJs8kRo >>539
sigsetjmp(), siglongjmp() ってのがあるので、そっち使った方が良さそうではあるな。
sigsetjmp(), siglongjmp() ってのがあるので、そっち使った方が良さそうではあるな。
542デフォルトの名無しさん
2018/08/27(月) 16:33:51.80ID:J1p6Vf0T Linuxとかならpthreadがあるのでわざわざ自分でディスパッチャ作ることはないと思うけど、組み込み用に簡易的に作ることはあるかもね。
俺は組み込みならprotothreadsのほうがシンプルで好き。
俺は組み込みならprotothreadsのほうがシンプルで好き。
543デフォルトの名無しさん
2018/08/27(月) 17:20:53.65ID:cJbIVPPr #include <signal.h>
void (*signal(int signum, void (*sighandler)(int signum)))(int signum);
この宣言が読めない
void (*signal(int signum, void (*sighandler)(int signum)))(int signum);
この宣言が読めない
544デフォルトの名無しさん
2018/08/27(月) 17:30:35.88ID:vY3QDx2y signal 関数名
signum 第1仮引数名
sighandler 第2仮引数名
sighandler ポインタ
*sighandler 関数
signum 第1仮引数名
signalの返却値はsighandlerと同じ型
signum 第1仮引数名
sighandler 第2仮引数名
sighandler ポインタ
*sighandler 関数
signum 第1仮引数名
signalの返却値はsighandlerと同じ型
545デフォルトの名無しさん
2018/08/27(月) 18:31:36.73ID:C1HpzEi0546デフォルトの名無しさん
2018/08/27(月) 18:49:30.60ID:C1HpzEi0547デフォルトの名無しさん
2018/08/27(月) 19:22:28.99ID:FN2jn8ES >>546
全て別の方法で実現しちゃうので、俺的にはlongjmpの必要性を感じないかな?
全て別の方法で実現しちゃうので、俺的にはlongjmpの必要性を感じないかな?
548デフォルトの名無しさん
2018/08/27(月) 19:30:11.24ID:m5aHtIH2 >>530
高度すぎてなに言ってるかわからん
高度すぎてなに言ってるかわからん
549デフォルトの名無しさん
2018/08/27(月) 19:46:09.70ID:nZJhjhuf まあデータの損傷をいきなりデータ構造そのものの破綻に結びつけるのは些か強引な論理展開ではあるな
550デフォルトの名無しさん
2018/08/27(月) 19:55:16.65ID:C1HpzEi0551デフォルトの名無しさん
2018/08/27(月) 20:08:36.09ID:FN2jn8ES >>550
こんな感じ。
OSのタスク切り替え処理
→普通にOSの機能を使う、カーネルなしで簡易ディスパッチャ実装はpthread
ブートローダーからアプリケーションへのジャンプ
→アドレス固定ならアドレスを関数ポインタにキャストしてジャンプ、またはインラインアセンブラ
リセット
→周辺機能やbssやdataセクションも初期化したいのでWDT等のCPUリセット機能を使う
例外処理
→密結合を避けるためオーソドックスに返り値で判定、最後にgoto使うかも?
そういや例外処理longjmpで思い出したけど、一昔以上前のCマガジンにマクロでC++と同じようなtry〜catch構文実装方法の記事があったけど、確かにそのマクロ内ではsetjmp/longjmp使ってたわ。
マクロでカプセル化してれば例外処理で使うかも。
こんな感じ。
OSのタスク切り替え処理
→普通にOSの機能を使う、カーネルなしで簡易ディスパッチャ実装はpthread
ブートローダーからアプリケーションへのジャンプ
→アドレス固定ならアドレスを関数ポインタにキャストしてジャンプ、またはインラインアセンブラ
リセット
→周辺機能やbssやdataセクションも初期化したいのでWDT等のCPUリセット機能を使う
例外処理
→密結合を避けるためオーソドックスに返り値で判定、最後にgoto使うかも?
そういや例外処理longjmpで思い出したけど、一昔以上前のCマガジンにマクロでC++と同じようなtry〜catch構文実装方法の記事があったけど、確かにそのマクロ内ではsetjmp/longjmp使ってたわ。
マクロでカプセル化してれば例外処理で使うかも。
552デフォルトの名無しさん
2018/08/27(月) 20:17:29.99ID:C1HpzEi0 カーネルなしでpthreadの意味がわからん
553デフォルトの名無しさん
2018/08/27(月) 20:21:53.00ID:FN2jn8ES554デフォルトの名無しさん
2018/08/28(火) 15:16:05.31ID:wM2MhSxp http://techtipshoge.blogspot.com/2011/02/blog-post.html
このサイトで、書いてることは正しいと思うしし、実際こうなるんだけど、俺の頭悪いせいでわからない。
駄目な例のsetStr(a)の a は、 &a[0] という”アドレス”を渡してる訳ではないんでしょうか?
なんで駄目な例だと上手くいかないのかという理屈がわからない・・・
このサイトで、書いてることは正しいと思うしし、実際こうなるんだけど、俺の頭悪いせいでわからない。
駄目な例のsetStr(a)の a は、 &a[0] という”アドレス”を渡してる訳ではないんでしょうか?
なんで駄目な例だと上手くいかないのかという理屈がわからない・・・
555デフォルトの名無しさん
2018/08/28(火) 15:16:57.00ID:wM2MhSxp あ、レスして気づいたけどcoutがあるってことはc++なのかな?
まあこれはprintfってことにしといてくださいw 重複質問になりそうなのでこちらで処理したい。
まあこれはprintfってことにしといてくださいw 重複質問になりそうなのでこちらで処理したい。
556さまよえる蟻人間 ◆T6xkBnTXz7B0
2018/08/28(火) 15:27:14.25ID:cEEOiaf2 newもC++のキーワードなんだけど。。
関数に実引数のポインタを渡すとその値が、対応する仮引数に代入(コピー)され、以後、仮引数は変数のように使える。
仮引数の値を変えてもコピーが書き換えられるだけで元の実引数の値には影響しない。
書き換えられるようにするには、書き換えたい場所のアドレスを渡して、*演算子か、[]演算子を使わないといけない。
関数に実引数のポインタを渡すとその値が、対応する仮引数に代入(コピー)され、以後、仮引数は変数のように使える。
仮引数の値を変えてもコピーが書き換えられるだけで元の実引数の値には影響しない。
書き換えられるようにするには、書き換えたい場所のアドレスを渡して、*演算子か、[]演算子を使わないといけない。
557デフォルトの名無しさん
2018/08/28(火) 15:27:46.08ID:10z9ufr/ 駄目な例のa = new char [8];はmainのaの複製への代入なのでmainのaはNULLのまま
良い例の*a = new char [8];はmainのaそのものへの代入なので期待した結果が得られる
良い例の*a = new char [8];はmainのaそのものへの代入なので期待した結果が得られる
558さまよえる蟻人間 ◆T6xkBnTXz7B0
2018/08/28(火) 15:37:02.95ID:cEEOiaf2 関数呼び出しのとき、実引数がどこにコピーされるかというと、「スタック」という積み上げ式のメモリーブロックか、一時的なCPUレジスタが使われる。
インラインではない関数呼び出しにおいては、関数の戻り先のアドレスと、仮引数のデータがスタックに積み上げられる。
積み上げ式だから、自分自身の関数を呼び出しても動作する。これを「再帰呼び出し」という。
インラインではない関数呼び出しにおいては、関数の戻り先のアドレスと、仮引数のデータがスタックに積み上げられる。
積み上げ式だから、自分自身の関数を呼び出しても動作する。これを「再帰呼び出し」という。
559さまよえる蟻人間 ◆T6xkBnTXz7B0
2018/08/28(火) 15:39:32.69ID:cEEOiaf2 スタックの積み上げには限度がある。限度を超えると、スタックサイズが拡張されたり、異常終了する。
スタックの積み上げが限度を超えて異常な状態になることを「スタックオーバーフロー」という。
スタックの積み上げが限度を超えて異常な状態になることを「スタックオーバーフロー」という。
560デフォルトの名無しさん
2018/08/28(火) 15:52:37.71ID:wM2MhSxp すません。私の質問が曖昧だったので追加で
void setStr(int *a) {
a[0] = 10;
}
int main() {
int a[10];
setStr(&a[0]);
cout << a[0] << endl;
return 0;
}
例えば、この場合は、setStr(&a[0])として、その後、関数内でa[0]=10;と値を代入すればちゃんと 10 が出力されます。
前のHPの失敗例も同じくsetStr(a)としてアドレスを渡し、受け取りはポインタ変数なのに値は変わらない。
単に数値か文字列かの違いなんでしょうか?
void setStr(int *a) {
a[0] = 10;
}
int main() {
int a[10];
setStr(&a[0]);
cout << a[0] << endl;
return 0;
}
例えば、この場合は、setStr(&a[0])として、その後、関数内でa[0]=10;と値を代入すればちゃんと 10 が出力されます。
前のHPの失敗例も同じくsetStr(a)としてアドレスを渡し、受け取りはポインタ変数なのに値は変わらない。
単に数値か文字列かの違いなんでしょうか?
561デフォルトの名無しさん
2018/08/28(火) 16:00:50.42ID:Gzofmim2 とりあえず一度、配列とポインタに対する余計な先入観を捨てて素直に元サイトを読み込めば理解できると思うよ
一つの考え方に囚われ過ぎてると思う
一つの考え方に囚われ過ぎてると思う
562デフォルトの名無しさん
2018/08/28(火) 16:05:47.55ID:10z9ufr/ void setStr(char **a) これを
void setStr(int *a) こう読み替え
char *a = NULL; setStr(&a); これを
int a = 0; setStr(&a); こう読み替えてみそ
つまり char* → int と読み替えるんだ
ポインタ変数とアドレスは違うという話は
整数変数と整数は違うという話と同じだ
void setStr(int *a) こう読み替え
char *a = NULL; setStr(&a); これを
int a = 0; setStr(&a); こう読み替えてみそ
つまり char* → int と読み替えるんだ
ポインタ変数とアドレスは違うという話は
整数変数と整数は違うという話と同じだ
563デフォルトの名無しさん
2018/08/28(火) 16:17:43.85ID:LgBUyhOe まあスタック使えとは規格に書いてないんだけどね
564デフォルトの名無しさん
2018/08/28(火) 16:35:30.28ID:wM2MhSxp ああ分かった!
俺は自分で勝手に「char型のポインタ=文字列だ」と思い込んでて、そのせいで混乱してただけでした。
思い込み怖い・・・
void setStr(char *a) {
a[0]='a';
}
int main() {
char a[] = "test";
setStr(a);
cout << a << endl;
return 0;
}
これで「aest」と表示されたからピンときた。確かに失敗例はポインタ変数を渡しているだけだw
ありがとうございました。
俺は自分で勝手に「char型のポインタ=文字列だ」と思い込んでて、そのせいで混乱してただけでした。
思い込み怖い・・・
void setStr(char *a) {
a[0]='a';
}
int main() {
char a[] = "test";
setStr(a);
cout << a << endl;
return 0;
}
これで「aest」と表示されたからピンときた。確かに失敗例はポインタ変数を渡しているだけだw
ありがとうございました。
565デフォルトの名無しさん
2018/08/28(火) 18:19:39.20ID:4ROMapnq >>563
そりゃそうだよ、世の中にはスタックを持たないマシンもあるからな
そりゃそうだよ、世の中にはスタックを持たないマシンもあるからな
566デフォルトの名無しさん
2018/08/28(火) 18:33:43.92ID:oY+WdDFv ハードウェアスタックを持たなくて再帰呼び出し出来ないうんこ環境があるね
567デフォルトの名無しさん
2018/08/28(火) 18:38:07.52ID:h1lwFjom そういうのは自分で値を積み上げるように作るしかないな
568デフォルトの名無しさん
2018/08/28(火) 18:45:10.17ID:Gzofmim2 そういえばずいぶん昔に昔ながらのBASIC言語でクイックソートを実装したときに当然サブルーチンの再起呼び出しなど使えないので
自分で似たようなことをやったなあ
というか確か何かのプログラム認定試験の定番の出題テーマだった気がする
当時必死に勉強してたことを思い出した
自分で似たようなことをやったなあ
というか確か何かのプログラム認定試験の定番の出題テーマだった気がする
当時必死に勉強してたことを思い出した
569デフォルトの名無しさん
2018/08/28(火) 18:45:55.20ID:Gzofmim2 再起ってなんだ再帰の誤変換
570デフォルトの名無しさん
2018/08/28(火) 18:47:51.41ID:h1lwFjom 再帰 不能
571デフォルトの名無しさん
2018/08/28(火) 19:51:12.99ID:zI7irPVs ぴゅう太なんてレジスタがなかった
572デフォルトの名無しさん
2018/08/28(火) 19:56:09.59ID:c8HqOUoV573デフォルトの名無しさん
2018/08/28(火) 20:04:33.36ID:10z9ufr/ 制御記憶を主記憶とシェアするアーキテクチャはそんなに珍しくない
574デフォルトの名無しさん
2018/08/28(火) 20:09:30.18ID:c8HqOUoV 普通にR0とかのレジスタ名ついてるんだけど実体は内蔵RAMにマッピングされてるアーキテクチャならよく見るけど、外部RAMってのは初めて見たわ。
今もこういうアーキテクチャのCPUあるのかな?
今もこういうアーキテクチャのCPUあるのかな?
575デフォルトの名無しさん
2018/08/28(火) 20:15:00.09ID:Gymzh0gE ない
576デフォルトの名無しさん
2018/08/28(火) 20:25:08.96ID:10z9ufr/ ぴゅうたって内蔵RAMなんだっけ
577デフォルトの名無しさん
2018/08/28(火) 20:28:21.23ID:c8HqOUoV578デフォルトの名無しさん
2018/08/28(火) 20:53:39.14ID:UQgP5OTn579デフォルトの名無しさん
2018/08/28(火) 20:58:39.83ID:10z9ufr/ >>578
必ずしもマイクロ【コード】を入れるところじゃないんだけどね
たとえばメインフレームではDIAGNOSE命令で制御記憶を目的外使用なんてのをやってたよ
それやってるときはTestインジケーターが点灯することになってて
必ずしもマイクロ【コード】を入れるところじゃないんだけどね
たとえばメインフレームではDIAGNOSE命令で制御記憶を目的外使用なんてのをやってたよ
それやってるときはTestインジケーターが点灯することになってて
580デフォルトの名無しさん
2018/08/28(火) 21:38:04.13ID:UQgP5OTn >>579
> たとえばメインフレームではDIAGNOSE命令で制御記憶を目的外使用なんてのをやってたよ
そんな特殊な例出されてもなぁ w
そりゃ記憶装置だから他の物を入れることはできるよ
だから何? って話だけどな
> それやってるときはTestインジケーターが点灯することになってて
で、主記憶と共用ってどこのアーキテクチャなんだ?
> たとえばメインフレームではDIAGNOSE命令で制御記憶を目的外使用なんてのをやってたよ
そんな特殊な例出されてもなぁ w
そりゃ記憶装置だから他の物を入れることはできるよ
だから何? って話だけどな
> それやってるときはTestインジケーターが点灯することになってて
で、主記憶と共用ってどこのアーキテクチャなんだ?
581デフォルトの名無しさん
2018/08/28(火) 21:54:20.28ID:d5vKjLdu >>580
やめたれ w
やめたれ w
582デフォルトの名無しさん
2018/08/28(火) 22:02:06.14ID:lp3F9A9k それってセキュリティ上問題にならないのか?
583デフォルトの名無しさん
2018/08/28(火) 22:15:00.65ID:d5vKjLdu いまはやりのcore iのバグみたいな?
584デフォルトの名無しさん
2018/08/29(水) 23:07:37.73ID:E6lvAa/y メルトダウン事件移行もアップデートの度にどんどんコンパイルとか画像縮小なんかの処理が遅くなってる気がする
もう怖くて淫照は買えない
もう怖くて淫照は買えない
585デフォルトの名無しさん
2018/08/30(木) 05:50:33.67ID:zs5ycFHj ベンチマークしてる?
586デフォルトの名無しさん
2018/08/30(木) 08:20:17.62ID:cD6Bz7+B >>582
そりゃなるよ
命令の動作を書き換えるんだから何でもできちゃう
なのでDiag関連の命令はCE(カスタマーエンジニア)モードでしか使えないとかなってたはず
今時のCPUでもエラッタ対策としてマイクロコードの書換えするけどコード自体は暗号化されてる
この暗号化キーが漏れたらえらいことになると思う
そりゃなるよ
命令の動作を書き換えるんだから何でもできちゃう
なのでDiag関連の命令はCE(カスタマーエンジニア)モードでしか使えないとかなってたはず
今時のCPUでもエラッタ対策としてマイクロコードの書換えするけどコード自体は暗号化されてる
この暗号化キーが漏れたらえらいことになると思う
587デフォルトの名無しさん
2018/08/30(木) 10:16:53.98ID:zs5ycFHj X'83は単に特権命令ってだけだぜ
588デフォルトの名無しさん
2018/08/30(木) 12:25:33.09ID:cD6Bz7+B マシンによって違うのか?
M-180HはCEモードでないと動作しなかったが
M-180HはCEモードでないと動作しなかったが
589デフォルトの名無しさん
2018/08/30(木) 12:43:00.44ID:zs5ycFHj そういうことだね
俺んとこではPWOFFするオウンコードとかできたし
俺んとこではPWOFFするオウンコードとかできたし
590デフォルトの名無しさん
2018/08/30(木) 20:09:52.14ID:cD6Bz7+B それマイクロ関係ないだろ
591デフォルトの名無しさん
2018/08/31(金) 06:31:31.30ID:QWemr4wG すみません思い切り初心者の質問です。
printf("%s: abc", str);
↑こういう文が abcのみが変わる形で(str変数は変更されません)
沢山登場するプログラムを作っており コピペが面倒だしバグの温床になりそうなので
#defineマクロなどを使って引数にabcを指定すると上記の文がまるごと出力されるようにしたいと思いました。
そこで
#define PR_POS(_pos) printf("%s: _pos", str)
という定義を作ったのですが恐らく引用符の中身は変更されることはないので
#include <stdio.h>
#include <stdlib.h>
#define PR_POS(_pos) printf("%s: _pos\n", str)
int main(void) {
char str[256] = "text";
//printf("%s: abc\n", str);
PR_POS(abc);
exit(EXIT_SUCCESS);
}
というプログラムを作っても実際コンパイルしたものを実行すると
text: _pos
という望んでいない出力が返ってくるだけです
これを
text: abc
という出力にするにはどうすればいいでしょうか……。
printf("%s: abc", str);
↑こういう文が abcのみが変わる形で(str変数は変更されません)
沢山登場するプログラムを作っており コピペが面倒だしバグの温床になりそうなので
#defineマクロなどを使って引数にabcを指定すると上記の文がまるごと出力されるようにしたいと思いました。
そこで
#define PR_POS(_pos) printf("%s: _pos", str)
という定義を作ったのですが恐らく引用符の中身は変更されることはないので
#include <stdio.h>
#include <stdlib.h>
#define PR_POS(_pos) printf("%s: _pos\n", str)
int main(void) {
char str[256] = "text";
//printf("%s: abc\n", str);
PR_POS(abc);
exit(EXIT_SUCCESS);
}
というプログラムを作っても実際コンパイルしたものを実行すると
text: _pos
という望んでいない出力が返ってくるだけです
これを
text: abc
という出力にするにはどうすればいいでしょうか……。
592デフォルトの名無しさん
2018/08/31(金) 06:43:34.91ID:jQ6ZKbRR593デフォルトの名無しさん
2018/08/31(金) 06:44:40.48ID:Df6BGOL7 #define PR_POS(_pos) printf("%s: " #_pos, str)
594デフォルトの名無しさん
2018/08/31(金) 06:45:58.45ID:Df6BGOL7595591
2018/08/31(金) 07:04:03.05ID:QWemr4wG596デフォルトの名無しさん
2018/08/31(金) 07:18:20.44ID:4o8e5lPA #include <stdio.h>
#define DEBUG(fmt, ...) \
fprintf(stdout, "%s:%d #%s " fmt "\n", \
__FILE__, __LINE__, __func__, ##__VA_ARGS__);
初心者ならこのマクロを覚えておくと良いぞ。誰もが一度は使うはず。
#define DEBUG(fmt, ...) \
fprintf(stdout, "%s:%d #%s " fmt "\n", \
__FILE__, __LINE__, __func__, ##__VA_ARGS__);
初心者ならこのマクロを覚えておくと良いぞ。誰もが一度は使うはず。
597デフォルトの名無しさん
2018/08/31(金) 07:26:18.95ID:jQ6ZKbRR >>595
> しかもC99でも定められてるっぽい?
X 3010:2003 (ISO/IEC 9899:1999)
6.10.3.2 #演算子
制約
関数形式マクロの置換要素並びの中にある各#前処理字句の次の前処理字句は,仮引数でなければならない。
意味規則
置換要素並びの中で,仮引数の直前に#前処理字句がある場合,対応する実引数の前処理字句列のつづりを含んだ一つの単純文字列リテラル前処理字句によって,#前処理字句と仮引数を置き換える。(後略)
http://kikakurui.com/x3/X3010-2003-01.html
> しかもC99でも定められてるっぽい?
X 3010:2003 (ISO/IEC 9899:1999)
6.10.3.2 #演算子
制約
関数形式マクロの置換要素並びの中にある各#前処理字句の次の前処理字句は,仮引数でなければならない。
意味規則
置換要素並びの中で,仮引数の直前に#前処理字句がある場合,対応する実引数の前処理字句列のつづりを含んだ一つの単純文字列リテラル前処理字句によって,#前処理字句と仮引数を置き換える。(後略)
http://kikakurui.com/x3/X3010-2003-01.html
598デフォルトの名無しさん
2018/08/31(金) 07:48:00.90ID:QWemr4wG >>596
すいません。初心者なのにめちゃめちゃ上から目線みたいになってしまうんですが
assert()を使わないのはなぜですかね。
POSIX C99でも定義されているので ほとんどどのコンパイラでも処理できると思うんです。
すいません。初心者なのにめちゃめちゃ上から目線みたいになってしまうんですが
assert()を使わないのはなぜですかね。
POSIX C99でも定義されているので ほとんどどのコンパイラでも処理できると思うんです。
599デフォルトの名無しさん
2018/08/31(金) 08:16:53.54ID:4o8e5lPA600デフォルトの名無しさん
2018/08/31(金) 08:23:18.46ID:LcHwdHfr フィールドのエラーログ用に>>596みたいなコードをリリースバイナリにも埋めることがあるけど
その場合はassertじゃ役に立たないんだよな。
その場合はassertじゃ役に立たないんだよな。
601デフォルトの名無しさん
2018/08/31(金) 08:31:20.23ID:uM5wy4o0 斜め読みだけど、abcが変わってstrが変更されないならabcの方を文字列変数にしてprintfすれば良いんじゃね?
602デフォルトの名無しさん
2018/08/31(金) 08:33:49.15ID:CKe+Ima+603デフォルトの名無しさん
2018/08/31(金) 08:40:41.19ID:QWemr4wG604デフォルトの名無しさん
2018/08/31(金) 09:08:12.10ID:9zTxkh/J 本番のコードと差が出て邪魔なのでassertはあまり使いませんね。
どうせデバッガ使うというのもあるし。
どうせデバッガ使うというのもあるし。
605デフォルトの名無しさん
2018/08/31(金) 09:17:03.63ID:QWemr4wG >>604
本業の方の意見はほんとありがたいです。
コンパイルエラーと違ってassert(3)は実行時にエラーを吐くので同じ「実行するときに診断する」プログラムでassert(3)より高機能なデバッガ(GDBとか)を使うということですか?
---
>>591の処理ですが以下のように書き直したところ望み通りに動きました。
みなさまありがとうございます。感謝します。
#include <stdio.h>
#include <stdlib.h>
#define PR_POS(_pos) printf("%s:" #_pos "\n", str)
int main(void) {
char str[256] = "text";
//printf("%s: abc\n", str);
PR_POS(abc);
exit(EXIT_SUCCESS);
}
本業の方の意見はほんとありがたいです。
コンパイルエラーと違ってassert(3)は実行時にエラーを吐くので同じ「実行するときに診断する」プログラムでassert(3)より高機能なデバッガ(GDBとか)を使うということですか?
---
>>591の処理ですが以下のように書き直したところ望み通りに動きました。
みなさまありがとうございます。感謝します。
#include <stdio.h>
#include <stdlib.h>
#define PR_POS(_pos) printf("%s:" #_pos "\n", str)
int main(void) {
char str[256] = "text";
//printf("%s: abc\n", str);
PR_POS(abc);
exit(EXIT_SUCCESS);
}
606デフォルトの名無しさん
2018/08/31(金) 10:04:04.85ID:Qsv+Vg4k assertの使い道って「ここでは必ずhogeになる!」という意志をコードに残すという意味はあるかな。
言ってるとおりで動かすときはgdb使うし、開発中は単体テストで同等以上の確認するしで、実用性は今はあまり無いと思いますね。
言ってるとおりで動かすときはgdb使うし、開発中は単体テストで同等以上の確認するしで、実用性は今はあまり無いと思いますね。
607デフォルトの名無しさん
2018/08/31(金) 11:00:23.86ID:mNRFahys assertはどっちかつーと単体テストでよく使う
608デフォルトの名無しさん
2018/08/31(金) 12:32:32.62ID:QMdn6GpG 本番コードでもassert使うかな
ハードエラーみたいなのはカバーしきれない
ハードエラーみたいなのはカバーしきれない
609デフォルトの名無しさん
2018/08/31(金) 12:51:53.38ID:jQ6ZKbRR >>606
> assertの使い道って「ここでは必ずhogeになる!」という意志をコードに残すという意味はあるかな。
assertion の意味は主張だからむしろそれが正しいとも言えるな
> 実用性は今はあまり無いと思いますね。
最初作るときはそうでも改修時に全然触ってない所のassert()に引っかかることもあるから俺は基本入れてる
> assertの使い道って「ここでは必ずhogeになる!」という意志をコードに残すという意味はあるかな。
assertion の意味は主張だからむしろそれが正しいとも言えるな
> 実用性は今はあまり無いと思いますね。
最初作るときはそうでも改修時に全然触ってない所のassert()に引っかかることもあるから俺は基本入れてる
610デフォルトの名無しさん
2018/09/02(日) 07:11:07.60ID:667Fbrpy int a = 42;
a = a++;
↑これがコンパイルエラーになる理由って
「左辺aに対する代入と右辺aに対するインクリメントのどちらの演算を優先して処理するか不定である為」
で合ってますか? 不定じゃなくて未定義かも……。
a = a++;
↑これがコンパイルエラーになる理由って
「左辺aに対する代入と右辺aに対するインクリメントのどちらの演算を優先して処理するか不定である為」
で合ってますか? 不定じゃなくて未定義かも……。
611デフォルトの名無しさん
2018/09/02(日) 07:29:52.76ID:fa3EYjvI エラーになるか? 警告ではなく
612デフォルトの名無しさん
2018/09/02(日) 09:00:51.15ID:667Fbrpy >>611
-Werrorとかにしてました
-Werrorとかにしてました
613611
2018/09/02(日) 09:07:14.14ID:667Fbrpy >>611
あれ。すいません。よく分からなくなりました。
$ gcc -pedantic -std=c99 -Wall -Werror -O2
でコンパイルするとエラーになり停止しますが
$ icc -std=c99 -Wall -Werror -O2
でコンパイルするとあっさり通りますね……。
あれ。すいません。よく分からなくなりました。
$ gcc -pedantic -std=c99 -Wall -Werror -O2
でコンパイルするとエラーになり停止しますが
$ icc -std=c99 -Wall -Werror -O2
でコンパイルするとあっさり通りますね……。
614デフォルトの名無しさん
2018/09/02(日) 09:27:27.59ID:pzXMyV5h615デフォルトの名無しさん
2018/09/02(日) 09:59:41.19ID:GR8jnF/5 未定義だからコンパイラは何をしてもいい
616デフォルトの名無しさん
2018/09/02(日) 10:00:57.15ID:667Fbrpy >>614
ありがとうございます。
ちなみにicc (Intel(R) C/C++ Compiler)で-Wallおよび-Werrorオプションを設定したときは
警告もなにも出力されることなくコンパイルに成功してしまったんですが
理由とか分かりますかね。すいません。変な質問で……。
ありがとうございます。
ちなみにicc (Intel(R) C/C++ Compiler)で-Wallおよび-Werrorオプションを設定したときは
警告もなにも出力されることなくコンパイルに成功してしまったんですが
理由とか分かりますかね。すいません。変な質問で……。
617デフォルトの名無しさん
2018/09/02(日) 10:19:45.38ID:667Fbrpy >>614
あと,おっしゃる通り(すくなくともC99では)未定義でした。ありがとうございます。
> 直前の副作用完了点から次の副作用完了点までの間に,
> 式の評価によって一つのオブジェクトに格納された値を変更する回数は,高々1回でなければならない。
> さらに,変更後の値の読取りは,格納される値を決定するためだけに行われなければならない。
(JIS X 3010:2003 p.48; 参考 https://dotup.org/uploda/dotup.org1632204.png)
あと,おっしゃる通り(すくなくともC99では)未定義でした。ありがとうございます。
> 直前の副作用完了点から次の副作用完了点までの間に,
> 式の評価によって一つのオブジェクトに格納された値を変更する回数は,高々1回でなければならない。
> さらに,変更後の値の読取りは,格納される値を決定するためだけに行われなければならない。
(JIS X 3010:2003 p.48; 参考 https://dotup.org/uploda/dotup.org1632204.png)
618デフォルトの名無しさん
2018/09/02(日) 11:28:11.60ID:owKXNyzr >>610
そういう文法的になことには今は拘らない方がいい。(これは他言語学習者の方が酷いが)
上達の妨げにしかならない。
プログラミング言語は、「正しく書いたときに正しく動作する」ようにしか設計されていない。
特にCはそうだ。
意味不明なことを書いたらだいたい全て「未定義」であり、
意味不明なことを書く奴が悪い、ということになっている。
そしてそれが「未定義」と覚えることも、実質的な意味はない。
そんなコードはすぐに修正され、存在しないからだ。
実際、 a = a++; なんてコードは、どのOSSにもないはずだ。
この意味で、Cは全くの素人の入門者用ではない。
例えばC#はそこら辺厳しい言語で、そういった意味不明な書き方は全てコンパイルエラーにされるはず。
(さすがにその例では知らんが、例えば「未初期化の変数を使用」とかがエラーになる)
というか、マジでそのレベルならC#やった方がいい。
文法エラーなんてサジェストが出てOK押したら自動的に修正してくれる。
お前がどんな環境でやってるのかは知らんが。
ただ、こういった無駄な遠回りをしなくて済むだけでも、君にとってC#は有効だと思うよ。
つか、初心者は全ての文法を押さえないといけないと勘違いするようだが、それは間違いだ。
自分が使うだけの文法を押さえ、さっさと使うべきだ。
お前だって日本語の全ての漢字が読めるわけでもないのに日本語を使ってるだろ。
プログラミング言語も同様で、手段でしかないのだから、文法を一通り確認したら、
さっさとゲーム等何でもいいから作れ。
ネタがないのならそれはそもそも今プログラミングを学ぶ必要がないとも言えるし、
それでもやりたいのならラズパイでも買ってきてLEDチカチカでも目指せ。
文法を学ぶことが目的になってはいけない。それは完全に空回りだ。
そういう文法的になことには今は拘らない方がいい。(これは他言語学習者の方が酷いが)
上達の妨げにしかならない。
プログラミング言語は、「正しく書いたときに正しく動作する」ようにしか設計されていない。
特にCはそうだ。
意味不明なことを書いたらだいたい全て「未定義」であり、
意味不明なことを書く奴が悪い、ということになっている。
そしてそれが「未定義」と覚えることも、実質的な意味はない。
そんなコードはすぐに修正され、存在しないからだ。
実際、 a = a++; なんてコードは、どのOSSにもないはずだ。
この意味で、Cは全くの素人の入門者用ではない。
例えばC#はそこら辺厳しい言語で、そういった意味不明な書き方は全てコンパイルエラーにされるはず。
(さすがにその例では知らんが、例えば「未初期化の変数を使用」とかがエラーになる)
というか、マジでそのレベルならC#やった方がいい。
文法エラーなんてサジェストが出てOK押したら自動的に修正してくれる。
お前がどんな環境でやってるのかは知らんが。
ただ、こういった無駄な遠回りをしなくて済むだけでも、君にとってC#は有効だと思うよ。
つか、初心者は全ての文法を押さえないといけないと勘違いするようだが、それは間違いだ。
自分が使うだけの文法を押さえ、さっさと使うべきだ。
お前だって日本語の全ての漢字が読めるわけでもないのに日本語を使ってるだろ。
プログラミング言語も同様で、手段でしかないのだから、文法を一通り確認したら、
さっさとゲーム等何でもいいから作れ。
ネタがないのならそれはそもそも今プログラミングを学ぶ必要がないとも言えるし、
それでもやりたいのならラズパイでも買ってきてLEDチカチカでも目指せ。
文法を学ぶことが目的になってはいけない。それは完全に空回りだ。
619デフォルトの名無しさん
2018/09/02(日) 11:39:01.45ID:mdI4MGys やりたいことはシンプルに書けよってことだな。
最終的に a にどうなってほしいのか、それってもっと端的に書けないの?ってこと。
Cオタクになるのが目的じゃなければな。
最終的に a にどうなってほしいのか、それってもっと端的に書けないの?ってこと。
Cオタクになるのが目的じゃなければな。
620デフォルトの名無しさん
2018/09/02(日) 12:11:10.31ID:owKXNyzr (ちなみに補足)>>610
初心者には理解不能だと思うが、
「文法で許されていることが全て許される」環境なんて実質的に存在しない。
だから文法のコーナーケースについてはそもそも覚える必要がない。
(とはいえ、肝心のK&Rがフリーダムすぎて…ってのはあるが)
これは小説→ラノベの流れと同じで、
美辞麗句の技巧に走る必要はなく、簡単な文を書き連ねて面白い筋を書け、ということ。
プログラミングにおいてはこれが徹底していて、
同じ物なら、簡単な方が『常に』いい、ということになっている。
ただ、どこからが複雑なのか?というのは議論になる。
例えば自然言語で韓国が漢字を廃止した際、
「停留所」を「ばすが とまる ところ」と書き換え、老人が「舐めとんのか!」と切れた。
実際、全員が読める漢字を「もっと簡単に」という理由で平仮名に書き換えられても困るだろ。
丁度これと同じ(だが方向は逆)で、
新しいプログラミング言語は比較的すんなり書ける文法が用意されており、
それを使うべきかどうかでは揉めたりしている。
ただ、Cは古いのでまどろっこしい文法しかなく、ベタな書き方しか出来ない。
だから比較的この論争に巻き込まれることはないはず。
(それ以前に文法セット自体が小さくて、え?これだけ?のはずだが)
>>619
天然と養殖では学びのベクトルが逆なんだよな。
天然: 1を足したい → a++ と書くのか
養殖: a++と書くと → 1が足されるのか
結果、要因側をenumすると文法一覧になるのが養殖で、これが間違いの元だ。
そしてそれを馬鹿正直に一つずつ潰すから文法エリートになっていく。
そうではなく、要因側のenum結果はやりたいこと一覧になって、全部揃えばゲームが作れる!が正しい。
初心者には理解不能だと思うが、
「文法で許されていることが全て許される」環境なんて実質的に存在しない。
だから文法のコーナーケースについてはそもそも覚える必要がない。
(とはいえ、肝心のK&Rがフリーダムすぎて…ってのはあるが)
これは小説→ラノベの流れと同じで、
美辞麗句の技巧に走る必要はなく、簡単な文を書き連ねて面白い筋を書け、ということ。
プログラミングにおいてはこれが徹底していて、
同じ物なら、簡単な方が『常に』いい、ということになっている。
ただ、どこからが複雑なのか?というのは議論になる。
例えば自然言語で韓国が漢字を廃止した際、
「停留所」を「ばすが とまる ところ」と書き換え、老人が「舐めとんのか!」と切れた。
実際、全員が読める漢字を「もっと簡単に」という理由で平仮名に書き換えられても困るだろ。
丁度これと同じ(だが方向は逆)で、
新しいプログラミング言語は比較的すんなり書ける文法が用意されており、
それを使うべきかどうかでは揉めたりしている。
ただ、Cは古いのでまどろっこしい文法しかなく、ベタな書き方しか出来ない。
だから比較的この論争に巻き込まれることはないはず。
(それ以前に文法セット自体が小さくて、え?これだけ?のはずだが)
>>619
天然と養殖では学びのベクトルが逆なんだよな。
天然: 1を足したい → a++ と書くのか
養殖: a++と書くと → 1が足されるのか
結果、要因側をenumすると文法一覧になるのが養殖で、これが間違いの元だ。
そしてそれを馬鹿正直に一つずつ潰すから文法エリートになっていく。
そうではなく、要因側のenum結果はやりたいこと一覧になって、全部揃えばゲームが作れる!が正しい。
621デフォルトの名無しさん
2018/09/02(日) 12:24:17.27ID:667Fbrpy >>620
ちょっと反論があります。正直Cどころかプログラミング初学者なのですが……。
要するに私は養殖≠ナあり,そのような学び方では成長しないと仰りたいわけですよね。
まあ確かに自分でも「規格厨」というか,衒学的な性格をなのは自覚してます
しかしプログラミング言語というのは自然言語とは違う面が多々あると思います。
そして「文法を網羅すべきか」という点においては特に違うと思います。
プログラミング言語は少なくとも概念においては文法に正確に従えば定められた動作を確実に行ないます。
日本語の文法を遵守して話しても考えが伝わらないのとは全く異るところです。
だから私はプログラミング言語においては先に(かなり厳密に)文法を学ぶべきであり,
「文法を学ぶ」ことのなかには未定義動作に関する諸々の知識を習得することも含まれていると考えます。
偉そうにすいませんでした。まあ上手くいかなければまた考えを改めるつもりではいます。
ちょっと反論があります。正直Cどころかプログラミング初学者なのですが……。
要するに私は養殖≠ナあり,そのような学び方では成長しないと仰りたいわけですよね。
まあ確かに自分でも「規格厨」というか,衒学的な性格をなのは自覚してます
しかしプログラミング言語というのは自然言語とは違う面が多々あると思います。
そして「文法を網羅すべきか」という点においては特に違うと思います。
プログラミング言語は少なくとも概念においては文法に正確に従えば定められた動作を確実に行ないます。
日本語の文法を遵守して話しても考えが伝わらないのとは全く異るところです。
だから私はプログラミング言語においては先に(かなり厳密に)文法を学ぶべきであり,
「文法を学ぶ」ことのなかには未定義動作に関する諸々の知識を習得することも含まれていると考えます。
偉そうにすいませんでした。まあ上手くいかなければまた考えを改めるつもりではいます。
622デフォルトの名無しさん
2018/09/02(日) 12:32:31.40ID:mdI4MGys やりたいことを素直に書いたつもりで未定義な文法になってしまうなら、もっと論理を考えた方がいいかも。
やりたいことを行う手順を整理できてないってことだと思うよ。
a = a++; ということが結局どういう動作するのかを知ることより、何をしたくてそういう(矛盾をはらむ)書き方になったのかを自己分析した方がいい。
もちろん基本的な文法は勉強しておく前提はあるよ。
おれは養殖とか天然とかは分からんけど。
やりたいことを行う手順を整理できてないってことだと思うよ。
a = a++; ということが結局どういう動作するのかを知ることより、何をしたくてそういう(矛盾をはらむ)書き方になったのかを自己分析した方がいい。
もちろん基本的な文法は勉強しておく前提はあるよ。
おれは養殖とか天然とかは分からんけど。
■ このスレッドは過去ログ倉庫に格納されています
ニュース
- バリ島で男子生徒ら集団万引きか、防犯カメラ映像が拡散 京都の大谷中学・高校が「窃盗行為」謝罪★5 [七波羅探題★]
- 【速報】 米トランプ政権声明 「中国が台湾を奪おうとする、いかなる試みも阻止する」 中国「レッドラインだ」 ★2 [お断り★]
- 元プロ野球選手・堂上隼人(43)を20代女性2人へのわいせつ未遂容疑で8回目の逮捕…これまでの被害者は10代・20代の女性11人に [Anonymous★]
- 「残業キャンセル界隈」若者が増加?「職務放棄」との批判も…“定時退社の権利”どこまで通用するか [七波羅探題★]
- 【高校野球】なぜ『7回制』は反対多数でも止まらないか… 高野連が「全員の命」守るために貫く伝統より改革の姿勢 [冬月記者★]
- 体調不良で番組欠席続く山里亮太「この度は申し訳ございません」 [ひかり★]
- 日帝復活 ソースは高市 [402859164]
- 【高市悲報】中国軍「公海で空母の発着訓練するって事前通告したのになんで自衛隊機は急接近してきたんだ…?」中国軍困惑 [931948549]
- 【高市悲報】自衛隊「実は事前に現場海域で中国軍から空母での発着訓練をすると通告がありました」え…?😨😨 [931948549]
- 【悲報】高市早苗の出国税、日本人も対象にwmwmwwmwmwmwmw [834922174]
- 【高市速報】中国「このままだと日本が先制攻撃してくる」 [583597859]
- ダウンタウン+(月額1,100円)、再生回数100万超え連発wwwwwwwwwwwwwwwwwwww [329329848]
