[過去ログ]
C言語なら俺に聞け 163 (1002レス)
C言語なら俺に聞け 163 http://mevius.5ch.net/test/read.cgi/tech/1721137434/
上
下
前
次
1-
新
通常表示
512バイト分割
レス栞
このスレッドは過去ログ倉庫に格納されています。
次スレ検索
歴削→次スレ
栞削→次スレ
過去ログメニュー
99: デフォルトの名無しさん (ワッチョイ 65cd-RtM0) [sage] 2024/09/11(水) 22:04:51.93 ID:+V4MmH6p0 >>93 別にまともでもない 配列で定義してポインタで操作できるのがCの柔軟性だから idxにこだわると簡単な操作を複雑にしかねない http://mevius.5ch.net/test/read.cgi/tech/1721137434/99
100: デフォルトの名無しさん (ワッチョイ 6663-QZ+t) [sage] 2024/09/11(水) 23:11:00.81 ID:dQ20XCdF0 > while (*(t+i) = *s++) これは、 > while (*t++ = *s++) ;これがエラーになるのは何故かと言う質問から始まったからです t++がエラーで、t+iなら大丈夫が理解できれば解決だと思う ポインタの理解というのは壁にはなりますが、 乗り越えれば意外と簡単です、がんばれ! http://mevius.5ch.net/test/read.cgi/tech/1721137434/100
101: 警備員[Lv.7][新芽] (ワッチョイ f931-ztXh) [sage] 2024/09/12(木) 00:58:15.86 ID:QGeKjVfA0 >>92 ありがとうございました(sには実態がない) gcc -S test.c で .s を出力して眺めてみると、そのような感じになっていました 最適化と、AT&Tのオペランドが逆なのに慣れず読みにくかったですが "hoge" は「実体」が .data に置かれ、実行時にスタックにコピーされるのかと想像してましたが、実装がどうあれ、スタッフ上に "hoge" を置くための元を実体というのは違うと思いました 実際、"hoge" は .db でアロケートされず、4字は 32ビットの数値定数とされ、スタックに即値で転記されていました(実行時に生成されていました) # とても伝わりにくいと思いますが… http://mevius.5ch.net/test/read.cgi/tech/1721137434/101
102: はちみつ餃子 ◆8X2XSCHEME (ワッチョイ 7932-IU9Y) [sage] 2024/09/12(木) 08:54:43.60 ID:TbaO6N6i0 誰も説明してなかったことに気づいた。 E1[E2] が (*((E1)+(E2))) と等価であるというルールがある。 http://mevius.5ch.net/test/read.cgi/tech/1721137434/102
103: デフォルトの名無しさん (ワッチョイ 8a5c-8qrK) [] 2024/09/12(木) 21:59:57.92 ID:m7IlJoP80 それいにしえからのバカ発見器なんだが2024年になってもまだ動いてるとはC言語おそるべし http://mevius.5ch.net/test/read.cgi/tech/1721137434/103
104: 警備員[Lv.3][新芽] (ワッチョイ b68a-ztXh) [sage] 2024/09/12(木) 23:41:05.77 ID:+nQe2m720 次の方どうぞ http://mevius.5ch.net/test/read.cgi/tech/1721137434/104
105: デフォルトの名無しさん (ワッチョイ a6ee-865n) [sage] 2024/09/12(木) 23:43:09.62 ID:sEtsUeoh0 >>103 その自由度があるからC++でhtbl["key"]の様な事が出来る Cじゃ意味ない仕様だけど、禁止する必要も無かろう http://mevius.5ch.net/test/read.cgi/tech/1721137434/105
106: デフォルトの名無しさん (ワッチョイ 65cd-RtM0) [sage] 2024/09/13(金) 08:23:17.89 ID:ykZRrldI0 >>101 "hoge"は長さちょうど32ビットだから即値でスタックに書き込むようになってるということなら 最適化によってそこまで省略されてるわけでsに実体がない件とはあまり関係ないな 最適化オフにするかもっと長い文字列で実験してみては http://mevius.5ch.net/test/read.cgi/tech/1721137434/106
107: 警備員[Lv.5][新芽] (ワッチョイ 1eeb-ztXh) [sage] 2024/09/13(金) 09:12:47.27 ID:cjEIJ97r0 >>106 ありがとうございます もう少し正確に書けばよかったのですが、4字と '\0' の2回に分けて転記していました また、hogeを長くして(10字くらい?)試すと、やはり 4字ずつ整数にパックして即値で転記していました もっと長大な文字列試せば、別にアロケートされたそれをコピーするコードが吐かれたかもしれませんが、>>92 の指摘通り、実体がなく実行時に生成されることを確認できたとして打ち切ってしまいました http://mevius.5ch.net/test/read.cgi/tech/1721137434/107
108: はちみつ餃子 ◆8X2XSCHEME (ワッチョイ 65e8-hr+9) [sage] 2024/09/13(金) 10:12:57.71 ID:9XTDQHQm0 C の仕様は抽象機械の動作として記述される。 抽象機械の動作をどのように実際の機械と対応させるかは自由で、見かけ上の動作が同じならどういう機械語になってもいい。 生成された機械語から言語仕様を理解しようとすべきではないよ。 低レイヤプログラミングするならどう対応付くか知る必要がある場合もあるのは否定しないけど…… http://mevius.5ch.net/test/read.cgi/tech/1721137434/108
109: デフォルトの名無しさん (ブーイモ MM45-bJfQ) [sage] 2024/09/13(金) 10:23:10.52 ID:OBSQyTYbM その抽象機械の定義はしょせん後付け c言語のソースから生成されるマシン語の想像が付くようになるのはいいこと http://mevius.5ch.net/test/read.cgi/tech/1721137434/109
110: デフォルトの名無しさん (ワッチョイ 6663-QZ+t) [sage] 2024/09/13(金) 10:25:26.12 ID:y2ap91b60 C言語ハンドコンパイラ http://mevius.5ch.net/test/read.cgi/tech/1721137434/110
111: はちみつ餃子 ◆8X2XSCHEME (ワッチョイ 65e8-hr+9) [sage] 2024/09/13(金) 11:25:36.89 ID:9XTDQHQm0 >>109 機械語の想像がつくのが不要とも悪いとも言ってないよ。 そこから言語仕様を理解しようとすべきじゃないと述べてる。 できないから。 http://mevius.5ch.net/test/read.cgi/tech/1721137434/111
112: デフォルトの名無しさん (ワッチョイ a510-IFMZ) [sage] 2024/09/13(金) 11:46:29.60 ID:HT/On1VB0 所詮部外者の推測。 http://mevius.5ch.net/test/read.cgi/tech/1721137434/112
113: デフォルトの名無しさん (ワンミングク MM7a-k+ON) [sage] 2024/09/13(金) 12:46:10.11 ID:CiewPVvpM 今日は患者が多いですね http://mevius.5ch.net/test/read.cgi/tech/1721137434/113
114: デフォルトの名無しさん (ブーイモ MM45-bJfQ) [sage] 2024/09/13(金) 12:53:56.59 ID:OBSQyTYbM >>111 無用な心配 Xに溢れてるクソリプと同じ http://mevius.5ch.net/test/read.cgi/tech/1721137434/114
115: 警備員[Lv.1][新芽] (ワッチョイ 1e86-ztXh) [sage] 2024/09/13(金) 13:50:08.30 ID:cjEIJ97r0 >>108 ありがとうございます そもそも >>88 で sの実体がないとはどういうことか、というのが疑問だったためで、言語の仕様(というか実装)がどうかには着目していませんでした printf("%s\n", s); が .sではputs(s); に置き換えられていたり そうだよな〜 http://mevius.5ch.net/test/read.cgi/tech/1721137434/115
116: 警備員[Lv.1][新芽] (ワッチョイ 1e49-ztXh) [sage] 2024/09/13(金) 13:59:45.58 ID:cjEIJ97r0 あー、実装には注目してるのか>自分 http://mevius.5ch.net/test/read.cgi/tech/1721137434/116
117: はちみつ餃子 ◆8X2XSCHEME (ワッチョイ 7932-hr+9) [sage] 2024/09/13(金) 14:32:38.41 ID:7dvxgxgq0 この場合に限っては言語仕様としての理屈もあんまり違わんけどな。 ただ、正式な用語を知ってると細かいことを調べやすいみたいなのはあるので便利。 http://mevius.5ch.net/test/read.cgi/tech/1721137434/117
118: デフォルトの名無しさん (JP 0H3e-voeu) [sage] 2024/09/13(金) 16:10:44.34 ID:HymUJJD5H gccは配列に確保した短い文字列は最適化無しでもレジスターに載せてしまってるな ポインター文字列は最適化してもレジスターには載らない なので配列は配列として使った方が最適化で高速化される可能性があるという事だな http://mevius.5ch.net/test/read.cgi/tech/1721137434/118
119: はちみつ餃子 ◆8X2XSCHEME (ワッチョイ 7932-IU9Y) [sage] 2024/09/13(金) 16:26:39.79 ID:7dvxgxgq0 ポインター文字列って変な言葉だな。 この場の造語だと思うけど char *foo = "bar"; みたいなやつのことだよね? 文字列リテラルは静的記憶域期間 (寿命はプログラムの最初から最後まで) を持つオブジェクト。 どこかにある文字列をポインタで指しているという状況。 そのどこかにある文字は他のどこかから指し示されることもありうるので簡単には消えられない。 その一方で、配列の初期化子は配列を初期化する以外に使われる可能性がない。 http://mevius.5ch.net/test/read.cgi/tech/1721137434/119
120: デフォルトの名無しさん (アウアウエー Sa52-t/33) [] 2024/09/13(金) 16:36:31.22 ID:bblj+c3pa >>93 それのどこがマトモなんだよ >>94 の言い分の方が正しい 配列型が無いんだから http://mevius.5ch.net/test/read.cgi/tech/1721137434/120
121: デフォルトの名無しさん (アウアウエー Sa52-t/33) [] 2024/09/13(金) 16:38:54.03 ID:bblj+c3pa >>96 >t[100]を*(t+idx) t[100]を100[t] よりはマシ >>97 だよな http://mevius.5ch.net/test/read.cgi/tech/1721137434/121
122: デフォルトの名無しさん (JP 0H3e-voeu) [sage] 2024/09/13(金) 17:26:56.71 ID:HymUJJD5H >>119 んなこたーない char foo[] = "hoge"; char* bar = &foo[1]; /* 敢えてずらしてみる */ printf("bar -> %s\n", bar); で中身は何度も参照されるぞ gccで試してみたら敢えてずらしてポインターに代入されたとしても、レジスターに文字列を保持したままprintfに渡すというトリッキーなコードが生成されたw スタックに文字列を書き込んでそのアドレスを渡してるっぽい http://mevius.5ch.net/test/read.cgi/tech/1721137434/122
123: デフォルトの名無しさん (JP 0H3e-voeu) [sage] 2024/09/13(金) 17:45:50.36 ID:HymUJJD5H 短い配列文字列をポインターに代入したらレジスターに保持する最適化を諦めるかと思ったら、そうじゃなくて意地でもレジスターに保持したまま処理を進めるgccスゲーよw clangの場合はポインターも配列も常に静的に文字列を定義したものを使ってた http://mevius.5ch.net/test/read.cgi/tech/1721137434/123
124: デフォルトの名無しさん (ワッチョイ 6663-QZ+t) [sage] 2024/09/13(金) 18:12:32.57 ID:y2ap91b60 最近のCPUはレジスターに文字列格納できるんだな 何バイトくらいなら入るんだろうか http://mevius.5ch.net/test/read.cgi/tech/1721137434/124
125: デフォルトの名無しさん (JP 0H3e-voeu) [sage] 2024/09/13(金) 18:26:19.17 ID:HymUJJD5H gccの場合だと64bitだと8バイトだから最大7文字かなと思ったらレジスターを複数使ってでも載せようとしてたw 取り敢えず50文字まで試したけど全部レジスタに載ってた でもこの辺はレジスタの空き具合にもよるのか?詳しくは分からん http://mevius.5ch.net/test/read.cgi/tech/1721137434/125
126: デフォルトの名無しさん (ワッチョイ 6663-QZ+t) [sage] 2024/09/13(金) 18:41:27.03 ID:y2ap91b60 何か執念みたいなのを感じました笑 http://mevius.5ch.net/test/read.cgi/tech/1721137434/126
127: デフォルトの名無しさん (JP 0H3e-voeu) [sage] 2024/09/13(金) 18:50:06.89 ID:HymUJJD5H スマン…間違えた…orz 正確にはアセンブリコードに書かれてると言うべきだった movabsq $3833745473465760056, %rdx movabsq $3978425819141910832, %rax movq %rdx, 40(%rsp) movabsq $3544395820347831604, %rdx movq %rdx, 56(%rsp) ↑こんな感じで文字列が直値で表現されてて、スタックに積んで使ってた だったら静的に確保した方が速い気がするけど、やっぱりレジスターから直接使う事が有るのか? 取り敢えずコンパイラーが出力するコードに深入りしない方が良いって事は分かったw http://mevius.5ch.net/test/read.cgi/tech/1721137434/127
128: はちみつ餃子 ◆8X2XSCHEME (ワッチョイ 7932-IU9Y) [sage] 2024/09/13(金) 18:59:17.17 ID:7dvxgxgq0 >>122 その場合に参照されるのは foo であって、 "hoge" というリテラルではない。 "hoge" は foo を初期化する以外の用途に使われていない。 http://mevius.5ch.net/test/read.cgi/tech/1721137434/128
129: デフォルトの名無しさん (ワッチョイ 65cd-RtM0) [sage] 2024/09/13(金) 20:11:25.22 ID:ykZRrldI0 >>127 データセグメントに確保するよりも コードセグメントに書いたほうがすでにキャッシュに載ってるから高速なのかもな http://mevius.5ch.net/test/read.cgi/tech/1721137434/129
130: 警備員[Lv.5][新芽] (ワッチョイ 1e21-ztXh) [sage] 2024/09/13(金) 20:41:46.32 ID:cjEIJ97r0 速度の最適化か、生成されるオブジェクトの小ささかのトレードオフなんだろうね テスト用のコードは小さいから、後者は気にせずゴリゴリやってるのかな… http://mevius.5ch.net/test/read.cgi/tech/1721137434/130
131: デフォルトの名無しさん (ワッチョイ fa2d-2PHd) [sage] 2024/09/13(金) 23:38:57.27 ID:uRdGeQ4y0 世の中CやめてRustにしろだとか OpenAIの新AIが競プロで上位1割のプログラマに匹敵とか言うじゃない 今更人間がCを続ける意義ってなんなんだろう http://mevius.5ch.net/test/read.cgi/tech/1721137434/131
132: デフォルトの名無しさん (ワッチョイ 714e-/njq) [sage] 2024/09/14(土) 00:03:48.69 ID:UIMFiyQN0 COBOLみたくロストテクノロジーを理解出来る貴重な人になれる http://mevius.5ch.net/test/read.cgi/tech/1721137434/132
133: はちみつ餃子 ◆8X2XSCHEME (ワッチョイ 7932-hr+9) [sage] 2024/09/14(土) 00:19:19.91 ID:N2YvcTj50 低レイヤに関わる資料が C を前提に書かれていたりするのは普通のことなのでたとえ C でプログラミングしなくてもある程度は身に付いてないと困ることはあるだろう。 http://mevius.5ch.net/test/read.cgi/tech/1721137434/133
134: デフォルトの名無しさん (ワッチョイ a6e1-865n) [sage] 2024/09/14(土) 00:39:08.66 ID:0gsw2riP0 >>128 初期化する以外に参照されてないってのはおかしいだろ printfで中身が表示されてんだから ポインター変数のbar経由で中身を参照してるけど、中身は初期化で渡された文字列そのものだ そもそもリテラルが参照されてないという言い方もおかしい リテラルは単なる定数の簡略表記に過ぎず、ソースコード上だけの用語だ 実行時に消えてると言いたいのか? そんなわけない、全く消えてない http://mevius.5ch.net/test/read.cgi/tech/1721137434/134
135: デフォルトの名無しさん (ワッチョイ 6663-QZ+t) [sage] 2024/09/14(土) 00:51:01.21 ID:8t7wdnSS0 >>132 CobolやFortranはこれからも生き残るよ 多分 http://mevius.5ch.net/test/read.cgi/tech/1721137434/135
136: デフォルトの名無しさん (ワッチョイ 2a7c-9vXG) [] 2024/09/14(土) 08:27:14.72 ID:QgTfRJpW0 >>134 言ってることが意味不明。 textセグメントとかbssとかdataセグメントとか知らんの? http://mevius.5ch.net/test/read.cgi/tech/1721137434/136
137: はちみつ餃子 ◆8X2XSCHEME (ワッチョイ 7932-IU9Y) [sage] 2024/09/14(土) 08:59:02.76 ID:N2YvcTj50 >>134 > printfで中身が表示 意味が解らん。 表示されてる中身というのは foo の中身であってリテラルじゃないだろ。 > リテラルは単なる定数の簡略表記 整数リテラルなどは右辺値だが文字列リテラルに限っては左辺値。 文字列リテラルは実行フェイズにおいてオブジェクトとしての性質を持つということ。 (抽象機械の上では。) ただし、この文字列リテラルが型変換された結果によって生まれるポインタはアドレス定数の要件を満たす。 http://mevius.5ch.net/test/read.cgi/tech/1721137434/137
138: デフォルトの名無しさん (ワッチョイ a6e1-865n) [sage] 2024/09/14(土) 10:32:56.64 ID:0gsw2riP0 >>137 int i = 1; printf("i -> %d\n", i); この1は同じ様にリテラル表記以外に参照されてないというのか? http://mevius.5ch.net/test/read.cgi/tech/1721137434/138
139: はちみつ餃子 ◆8X2XSCHEME (ワッチョイ 7932-IU9Y) [sage] 2024/09/14(土) 10:49:21.06 ID:N2YvcTj50 >>138 前述の通り整数リテラルは右辺値 (rvalue)。 文字列リテラルは例外的な存在だ。 まず、 C の用語では「オブジェクト」と「値」は違う意味を持つ。 メモリ上のビットパターンがオブジェクトで、値は式の結果だ。 (規格用語では data storage だがここではあえてカジュアルな用語で言うことにする。) そして式の結果は lvalue と rvalue に区分される。 オブジェクトに結び付いている値が lvalue だと考えていい。 個々に規定があるので詳細は割愛するが、 式の中で変数名だとか単項 * 演算だとか [] とかがあればそれはメモリ上に存在してるのは明白だろ? そういうのが lvalue 。 たとえば 1+3+5 みたいな式があれば途中で 4 という値が生じるが、これは「どこ」にある? 場所に結び付いておらず、式が終われば破棄されることになってる。 こういうのが rvalue 。 ちなみに lvalue も rvalue が要求される文脈では rvalue に変換される。 (メモリから値が読みだされる。) http://mevius.5ch.net/test/read.cgi/tech/1721137434/139
140: はちみつ餃子 ◆8X2XSCHEME (ワッチョイ 7932-IU9Y) [sage] 2024/09/14(土) 12:58:36.93 ID:N2YvcTj50 >>138 このときの 1 というリテラルは (rvalue の) 1 を返す式で、その値が i にコピーされた後で寿命を終えて消滅する。 printf の引数の i で取り出される 1 は i に入っている 1 であってリテラルの 1 じゃない。 整数リテラルはあくまでも整数を返す (生成すると言ってもいいかも?) 式であって、メモリ上のどこかにあるオブジェクトというわけじゃない。 http://mevius.5ch.net/test/read.cgi/tech/1721137434/140
141: デフォルトの名無しさん (ワッチョイ a6e1-865n) [sage] 2024/09/14(土) 13:32:49.89 ID:0gsw2riP0 >>140 1は破棄されて"hoge"は破棄されないんだろ? だから参照されてんじゃん http://mevius.5ch.net/test/read.cgi/tech/1721137434/141
142: はちみつ餃子 ◆8X2XSCHEME (ワッチョイ 7932-hr+9) [sage] 2024/09/14(土) 13:40:20.14 ID:N2YvcTj50 >>141 >>122 の bar が参照しているのは文字列リテラルからコピーされた配列であって文字列リテラルではない。 文字列リテラルが破棄されないこととは独立した話だよ。 http://mevius.5ch.net/test/read.cgi/tech/1721137434/142
143: デフォルトの名無しさん (ワッチョイ a6e1-865n) [sage] 2024/09/14(土) 13:43:47.04 ID:0gsw2riP0 >>142 barは配列のコピーじゃないだろ ポインターなんだから コピーしてるのはアドレス値だぞ http://mevius.5ch.net/test/read.cgi/tech/1721137434/143
144: はちみつ餃子 ◆8X2XSCHEME (ワッチョイ 7932-hr+9) [sage] 2024/09/14(土) 13:55:39.65 ID:N2YvcTj50 >>143 そのポインタが指しているという意味で参照してると言ってる。 なにを言いたいんだ? 論点は「配列の初期化子として現れる文字列リテラルは配列の初期化以外に使われる可能性がない」という話だろ。 http://mevius.5ch.net/test/read.cgi/tech/1721137434/144
145: デフォルトの名無しさん (ワッチョイ 6663-QZ+t) [sage] 2024/09/14(土) 14:05:45.99 ID:8t7wdnSS0 > char foo[] = "hoge"; > char* bar = &foo[1]; /* 敢えてずらしてみる */ > bar が参照しているのは文字列リテラルからコピーされた配列であって文字列リテラルではない。 説明がよく分からないが、barは、fooではなく、どこかにコピーした別の文字列なり配列を参照していると言うことか? http://mevius.5ch.net/test/read.cgi/tech/1721137434/145
146: はちみつ餃子 ◆8X2XSCHEME (ワッチョイ 7932-IU9Y) [sage] 2024/09/14(土) 14:20:52.41 ID:N2YvcTj50 >>145 bar はどうでもいいよ。 それは要らん間接参照を入れて例としてよくわからんようになってるから 飛び飛びになってる私の書いてることをあらためてまとめると ・ char foo[] = "hoge"; といったような記述があれば "hoge" によって foo を初期化する。 ・ このときの文字列リテラル "hoge" は foo を初期化するだけに使われて他からアクセスされる可能性がない。 ・ 言語規格の建前上は文字列リテラルの寿命はプログラムの最初から最後までだが…… ・ この場合は他からアクセスされる可能性がないから機械語レベルでは文字列リテラルは最適化で消えて (即値としてコードに埋め込んで) も問題にならない。 http://mevius.5ch.net/test/read.cgi/tech/1721137434/146
147: デフォルトの名無しさん (ブーイモ MM0a-bJfQ) [sage] 2024/09/14(土) 16:37:38.90 ID:kHQOYHTcM つまり >>118 でgccが文字列を即値にする最適化の条件を推察したら はちみつ餃子が規格の観点で説明が不適切ってぼこってるわけか? 前者の情報のほうが有益だわ http://mevius.5ch.net/test/read.cgi/tech/1721137434/147
148: はちみつ餃子 ◆8X2XSCHEME (ワッチョイ 7932-hr+9) [sage] 2024/09/14(土) 16:47:20.53 ID:N2YvcTj50 >>147 補足したつもりだが。 どう最適化するにしても規格に反する挙動にしてはならない (したら規格に対応しているとは名乗れない) からどうしてそれで規格に反しないのかの観点から説明した。 http://mevius.5ch.net/test/read.cgi/tech/1721137434/148
149: デフォルトの名無しさん (ワッチョイ 8af5-/VPw) [sage] 2024/09/14(土) 17:01:46.57 ID:5H/bnNk90 最適化でどうなるかを考えながらC書くくらいならもうアセンブリ書いたほうが良いと思う http://mevius.5ch.net/test/read.cgi/tech/1721137434/149
150: デフォルトの名無しさん (ワッチョイ a6e1-865n) [sage] 2024/09/14(土) 17:07:34.51 ID:0gsw2riP0 >>146 はちみつは文字列リテラルがアセンブリソースの段階で"hoge"と書かれてなければ消えてると思ってんだなw 例え命令コードの即値で書かれていても消えてる訳じゃないからー!残念! だから話が噛み合わなかったんだw まぁ強いて言えば、最適化でデータの表現法方を変えても構わないって言えば良い http://mevius.5ch.net/test/read.cgi/tech/1721137434/150
151: デフォルトの名無しさん (ワッチョイ a6e1-865n) [sage] 2024/09/14(土) 17:14:48.19 ID:0gsw2riP0 x = 1; ← 最適化で消えても構わない x = 2; 最適化で消えても構わないってこういうことを言うんだよ char foo[] = "hoge"; "hoge"は消えて良い訳ないだろw gccは実際、命令コードに文字列を埋め込んでスタックに生成してるが、その文字列はポインター変数を使えば参照可能だ http://mevius.5ch.net/test/read.cgi/tech/1721137434/151
152: はちみつ餃子 ◆8X2XSCHEME (ワッチョイ 7932-IU9Y) [sage] 2024/09/14(土) 17:26:48.38 ID:N2YvcTj50 >>149 それはそう。 原則としては言語の理屈に従っておくのが良い。 繰り返すけど、少なくとも初心者に対して低レイヤの観点で C を説明するのは筋が悪いと思う。 http://mevius.5ch.net/test/read.cgi/tech/1721137434/152
153: はちみつ餃子 ◆8X2XSCHEME (ワッチョイ 7932-IU9Y) [sage] 2024/09/14(土) 17:33:13.32 ID:N2YvcTj50 >>151 > 参照可能だ その時参照してるのはスタック上にある配列であって、文字列リテラルではないってのを俺は何度書けばいいんだ? 文字列リテラルは本来は「プログラムの開始から終わりまでの寿命を持つオブジェクト」としてあらねばならないのが、 実際には文字列リテラルではない形になってることを「消えてる」と表現したのは確かに微妙な表現だったかもしれないが、 有るべき場所から消えてるんだからそんくらいわかるだろ。 そもそも最初は char* foo = "hoge"; との対比で言ってたんだから。 http://mevius.5ch.net/test/read.cgi/tech/1721137434/153
154: デフォルトの名無しさん (ワッチョイ 8a56-/VPw) [sage] 2024/09/14(土) 18:13:05.20 ID:5H/bnNk90 はちみつ餃子の説明はたぶん、C++ の考え方が混ざっていないか C で配列の初期化子に文字列リテラルが書けるのはあくまで文字列リテラル限定であって、それは式として扱われるのではなく、lvalue も rvalue もクソもないということだと思うが http://mevius.5ch.net/test/read.cgi/tech/1721137434/154
155: はちみつ餃子 ◆8X2XSCHEME (ワッチョイ 7932-IU9Y) [sage] 2024/09/14(土) 18:35:19.29 ID:N2YvcTj50 >>154 初期化子の文法の一部であって式の規則の適用範囲外じゃないの?ってことだよね? 6.7.8 を見てこの場合でも式だと解釈してるけど、そういわれたらちょっと自信がないかも。 http://mevius.5ch.net/test/read.cgi/tech/1721137434/155
156: デフォルトの名無しさん (ワッチョイ a6e1-865n) [sage] 2024/09/14(土) 18:53:38.72 ID:0gsw2riP0 >>153 その配列に格納されているデータが文字列リテラルから生成された文字列(の実体)だろ 厳密に言いたいなら、文字列リテラルはコンパイル時に存在さえしてれば良いものなんだよ 何しろ「リテラル」だから それを生存期間だの実行時の実体とごっちゃにしてるから訳分かんないことになんだよ コンパイル時にさえ存在してれば良いという事を実行時には消えてても良いとか言っちゃってんでしょ? http://mevius.5ch.net/test/read.cgi/tech/1721137434/156
157: デフォルトの名無しさん (ワッチョイ a6e1-865n) [sage] 2024/09/14(土) 19:03:33.67 ID:0gsw2riP0 char foo[] = { 'h', 'o', 'g', 'e', 0 }; 文字列リテラルは↑のシンタックスシュガーだ 初期化子は消えても構わないのか? 初期化子が生成した文字列は参照出来ないと言うのか? http://mevius.5ch.net/test/read.cgi/tech/1721137434/157
158: デフォルトの名無しさん (ワッチョイ 8a56-/VPw) [sage] 2024/09/14(土) 19:10:37.88 ID:5H/bnNk90 >>155 https://en.cppreference.com/w/c/language/array_initialization ここ参考にしてたから文法定義の時点で式じゃないと思ってたけど、ちゃんと規格上は式としてのパースではあったね、すまない 改めて C99(でいいんだよね、6.7.8 ってことは)の draft 読んでみたけど、文字列リテラルで初期化できるのは 6.7.8.14,15 で特殊に定義された意味論であって、やっぱり式扱いじゃないんじゃないかね http://mevius.5ch.net/test/read.cgi/tech/1721137434/158
159: はちみつ餃子 ◆8X2XSCHEME (ワッチョイ 7932-hr+9) [sage] 2024/09/14(土) 19:58:20.45 ID:N2YvcTj50 >>154 結果的な挙動からするとどっちでも良いから書いてないだけかも。 http://mevius.5ch.net/test/read.cgi/tech/1721137434/159
160: デフォルトの名無しさん (ワッチョイ 6663-QZ+t) [sage] 2024/09/14(土) 20:16:47.07 ID:8t7wdnSS0 皆拘らずに使っているのに言うのもあれなんだが C言語にはC++で言う参照はありません http://mevius.5ch.net/test/read.cgi/tech/1721137434/160
161: デフォルトの名無しさん (ワッチョイ a6b2-Z1Qu) [sage] 2024/09/14(土) 21:01:12.02 ID:NQ2pFzob0 hogeは破棄されないって一人がんばってるID:0gsw2riP0を救済して差し上げたいが……自分も完全にわかってないのでできない。 http://mevius.5ch.net/test/read.cgi/tech/1721137434/161
162: デフォルトの名無しさん (ワッチョイ 65cd-RtM0) [sage] 2024/09/14(土) 21:04:22.62 ID:tDLmxNl+0 実在するのはfoo[]だけで 文字列"hoge"は破壊どころか最初からあっても無くてもいいというのがここまでにわかったことだろ http://mevius.5ch.net/test/read.cgi/tech/1721137434/162
163: デフォルトの名無しさん (ワッチョイ 7910-VVra) [] 2024/09/14(土) 22:15:49.35 ID:zMI9sEnq0 配列と別に文字列もどこか別に確保しといて何の意味があるんだよ この形で配列作る度に二倍メモリ食うことになるじゃないか http://mevius.5ch.net/test/read.cgi/tech/1721137434/163
164: はちみつ餃子 ◆8X2XSCHEME (ワッチョイ 7932-IU9Y) [sage] 2024/09/14(土) 22:32:05.03 ID:N2YvcTj50 >>163 せやで。 だから最適化の余地があるという話をしてる。 http://mevius.5ch.net/test/read.cgi/tech/1721137434/164
165: デフォルトの名無しさん (ワッチョイ 6663-QZ+t) [sage] 2024/09/14(土) 22:34:31.27 ID:8t7wdnSS0 ここで最適化の話は混ぜない方が良い http://mevius.5ch.net/test/read.cgi/tech/1721137434/165
166: デフォルトの名無しさん (ワッチョイ a6e1-865n) [sage] 2024/09/14(土) 23:00:09.33 ID:0gsw2riP0 >>163 clangは配列でも文字列リテラルは残ってるよ ここって想像だけで語るアホばっかだなw リテラルはコンパイル時のみに必要 それとは別に実行時にリテラルを実体化した値が存在する 基本的にrvalueだ でないと当然初期化が出来ない この値をはちみつは無視して語っている http://mevius.5ch.net/test/read.cgi/tech/1721137434/166
167: デフォルトの名無しさん (ワッチョイ a6e1-865n) [sage] 2024/09/14(土) 23:04:40.23 ID:0gsw2riP0 はちみつはリテラルはコンパイル時にのみ必要な事と、実行時には必要な初期値(rvalue)を最適化で命令コードに埋め込む事を消えたと表現して、ごっちゃにしてるアホ これが結論 http://mevius.5ch.net/test/read.cgi/tech/1721137434/167
168: デフォルトの名無しさん (ワッチョイ a6e1-865n) [sage] 2024/09/14(土) 23:11:36.67 ID:0gsw2riP0 リテラルは参照されないと言ってるのがその証拠 そりゃコンパイル時にのみに必要なその場でデータ構造を表現するリテラルを、実行時に参照出来る訳ないだろw それが出来るのはコードをデータとして表現してるLisp だけだ C++のテンプレートでも無理 C++のconstevalなら可能になった std::formatはそれで実装可能になった 実行時には初期化の為のrvalueが絶対に存在する http://mevius.5ch.net/test/read.cgi/tech/1721137434/168
169: デフォルトの名無しさん (ワッチョイ a6e1-865n) [sage] 2024/09/14(土) 23:13:53.14 ID:0gsw2riP0 constevalも文字列リテラルを参照可能なのはコンパイル時のみだった… やっぱり真に実行時に文字列リテラルを参照可能なのはLisp だけだな http://mevius.5ch.net/test/read.cgi/tech/1721137434/169
170: デフォルトの名無しさん (ワッチョイ 8a56-/VPw) [sage] 2024/09/14(土) 23:40:13.14 ID:5H/bnNk90 >>1 の C17 ドラフトのリンク C++17 のやつじゃん 次スレ立てるならこれに変えといて https://web.archive.org/web/20181230041359/http://www.open-std.org/jtc1/sc22/wg14/www/abq/c17_updated_proposed_fdis.pdf http://mevius.5ch.net/test/read.cgi/tech/1721137434/170
171: はちみつ餃子 ◆8X2XSCHEME (ワッチョイ 7932-IU9Y) [sage] 2024/09/14(土) 23:53:27.27 ID:N2YvcTj50 >>167 起きていることは >>127 でこれ以上なく具体的に説明されてるんだから改めて厳密に表現しないと理解できないとは思わなかったんだよ。 >>168 文字列リテラルが静的記憶域期間を持つことは 6.4.5 に書かれてる。 実行フェイズに存在するオブジェクトだよ。 (最適化を抜きにして仕様通りに解釈すれば。) 配列の初期化子として現れる文字列リテラルの扱いは微妙かもという話が >>154 >>158 の指摘だが、 記憶域期間についての記述は文脈を指定せず文字列リテラル全部を対象にした記述に見える。 http://mevius.5ch.net/test/read.cgi/tech/1721137434/171
172: デフォルトの名無しさん (ワッチョイ d7cd-qbvN) [sage] 2024/09/15(日) 00:57:56.19 ID:/wZr5+b/0 >>163 そりゃ書き換える場合があるからでしょー 一個しかなかったら関数呼ばれるたびに初期値も書き換わってしまう なんで悩んでるのこの人? constつけたら一個ですむだろ多分 http://mevius.5ch.net/test/read.cgi/tech/1721137434/172
173: デフォルトの名無しさん (ワッチョイ ffe1-1pYN) [sage] 2024/09/15(日) 01:17:55.27 ID:STy65/7c0 >>171 > 実行フェイズに存在するオブジェクトだよ。 存在してんじゃねーかよ! これが最適化で消えて良いかの話だよ! gccの場合は命令コードに埋め込んでるけど、消えてる訳じゃないし、別のポインターから参照可能だ http://mevius.5ch.net/test/read.cgi/tech/1721137434/173
174: はちみつ餃子 ◆8X2XSCHEME (ワッチョイ f732-vU+L) [sage] 2024/09/15(日) 01:30:47.17 ID:B6k8li/O0 >>173 配列とその初期化子として現れる文字列リテラルが別の存在だってことが俺が何度も書いてることだよ。 これがそんなに何度も何度も何度も何度も書かないと理解できないようなことか? 別のポインタは配列を指せるが、その初期化子として現れる文字列リテラルを指せるわけじゃない。 char* foo = "hoge"; のようなケースではポインタ foo は文字列リテラルを指してるということと対比しての話だぞ。 http://mevius.5ch.net/test/read.cgi/tech/1721137434/174
175: デフォルトの名無しさん (ワッチョイ ffe1-1pYN) [sage] 2024/09/15(日) 01:32:35.13 ID:STy65/7c0 ちなみに「文字列リテラル」が「実行時」に存在してる訳では全くない はちみつはそこを勘違いしてる 静的記憶期間というのはスコープの事だ まぁエクステントと言った方が正確だが それはコンパイラーが理解できるものだが、それと「実行時」に存在する値を結びつけてはいけないし関係無い DLLだとしたら静的記憶期間の変数も実行時には存在しない可能性もある スレッドローカルストレージの変数もそうだな 要するに文字列リテラルで生成されたデータは実行時には確実にアクセス可能で、消えてるなんて全くあり得ない それをずっと言ってる http://mevius.5ch.net/test/read.cgi/tech/1721137434/175
176: デフォルトの名無しさん (ワッチョイ ffe1-1pYN) [sage] 2024/09/15(日) 01:38:12.52 ID:STy65/7c0 >>174 > 文字列リテラルを指せるわけじゃない。 はい、これが間違いの全て 文字列リテラルはコンパイラーだけが理解できる「構文」に過ぎない それを実行時にさせないとはこれいかに?w 文字列リテラルは「実行時」には何て名前になってんだ? 配列でもないぞ 配列に代入される前のrvalueの事だ まぁ文字列は例外的にlvalueにもなれるが、rvalueであることには違いない http://mevius.5ch.net/test/read.cgi/tech/1721137434/176
177: デフォルトの名無しさん (ワッチョイ 9f56-3vlU) [sage] 2024/09/15(日) 01:45:15.62 ID:hg9QOZOF0 >>171 なんかいろいろ書いたけど最終的には自分もそれで合っていると思う 実用上は正直どこで役に立つのかあまり思いつかないが、規格上どういう建て付けになってるのかはとりあえず理解できたかも というか、実用上あんまり役に立つわけじゃないから今まで調べもしなかったというか 規格上は「リテラル」は存在せず integer/enumeration/floating/character は定数なんですね それで定数は記憶域期間を持たない 文字列リテラルは静的記憶域期間を持つ 複合リテラルは関数本体の外か中かに応じて静的/自動記憶域期間を持つ、と うーんでもなあ 某言語でいきなり &1 とか書けるの知ってたら別に定数にも記憶域期間持たせればいいじゃんとか思っちゃうなあ とりあえずそうなっているというだけか http://mevius.5ch.net/test/read.cgi/tech/1721137434/177
178: はちみつ餃子 ◆8X2XSCHEME (ワッチョイ f732-vU+L) [sage] 2024/09/15(日) 01:46:17.50 ID:B6k8li/O0 >>175 > 静的記憶期間というのはスコープの事 ちがう。 記憶域期間はオブジェクトの寿命の区分。 6.2.4 を参照のこと。 寿命の区分が設定されている以上はオブジェクト (メモリ上のどこかにある) のこと。 > 文字列リテラルで生成されたデータは実行時には確実にアクセス可能で、消えてるなんて全くあり得ない 関数 (C のプログラムは関数の集合なので実質的にプログラムの全て) はオブジェクトではない。 私が「消える」と表現したのはこの意識があったからだが、機械語のレベルでどこかには存在するという意味ではそりゃ存在するだろう。 (同じ内容が連続する配列だったらループで書き込むような形にすることもあるかもしれない。) 配列の初期化子としての文字列リテラルは本来あるべき場所 (オブジェクト) から最適化で消えてるし、ポインタで指すことは出来ない。 http://mevius.5ch.net/test/read.cgi/tech/1721137434/178
179: はちみつ餃子 ◆8X2XSCHEME (ワッチョイ f732-vU+L) [sage] 2024/09/15(日) 01:53:34.48 ID:B6k8li/O0 >>177 C++ の右辺値参照も左辺値参照も左辺値なんだよね。 参照を経由したら左辺値になるなら最初からそう出来ないか? と思ったことはある。 http://mevius.5ch.net/test/read.cgi/tech/1721137434/179
メモ帳
(0/65535文字)
上
下
前
次
1-
新
書
関
写
板
覧
索
設
栞
歴
あと 823 レスあります
スレ情報
赤レス抽出
画像レス抽出
歴の未読スレ
AAサムネイル
Google検索
Wikipedia
ぬこの手
ぬこTOP
0.015s