[過去ログ] C言語なら俺に聞け 163 (1002レス)
上下前次1-新
このスレッドは過去ログ倉庫に格納されています。
次スレ検索 歴削→次スレ 栞削→次スレ 過去ログメニュー
144: はちみつ餃子◆8X2XSCHEME (ワッチョイ 7932-hr+9) 2024/09/14(土)13:55 ID:N2YvcTj50(6/14) AAS
>>143
そのポインタが指しているという意味で参照してると言ってる。
なにを言いたいんだ?
論点は「配列の初期化子として現れる文字列リテラルは配列の初期化以外に使われる可能性がない」という話だろ。
145(1): (ワッチョイ 6663-QZ+t) 2024/09/14(土)14:05 ID:8t7wdnSS0(2/4) AAS
> char foo[] = "hoge";
> char* bar = &foo[1]; /* 敢えてずらしてみる */
> bar が参照しているのは文字列リテラルからコピーされた配列であって文字列リテラルではない。
説明がよく分からないが、barは、fooではなく、どこかにコピーした別の文字列なり配列を参照していると言うことか?
146(1): はちみつ餃子◆8X2XSCHEME (ワッチョイ 7932-IU9Y) 2024/09/14(土)14:20 ID:N2YvcTj50(7/14) AAS
>>145
bar はどうでもいいよ。 それは要らん間接参照を入れて例としてよくわからんようになってるから
飛び飛びになってる私の書いてることをあらためてまとめると
・ char foo[] = "hoge"; といったような記述があれば "hoge" によって foo を初期化する。
・ このときの文字列リテラル "hoge" は foo を初期化するだけに使われて他からアクセスされる可能性がない。
・ 言語規格の建前上は文字列リテラルの寿命はプログラムの最初から最後までだが……
・ この場合は他からアクセスされる可能性がないから機械語レベルでは文字列リテラルは最適化で消えて (即値としてコードに埋め込んで) も問題にならない。
147(1): (ブーイモ MM0a-bJfQ) 2024/09/14(土)16:37 ID:kHQOYHTcM(1) AAS
つまり
>>118 でgccが文字列を即値にする最適化の条件を推察したら
はちみつ餃子が規格の観点で説明が不適切ってぼこってるわけか?
前者の情報のほうが有益だわ
148: はちみつ餃子◆8X2XSCHEME (ワッチョイ 7932-hr+9) 2024/09/14(土)16:47 ID:N2YvcTj50(8/14) AAS
>>147
補足したつもりだが。
どう最適化するにしても規格に反する挙動にしてはならない (したら規格に対応しているとは名乗れない) からどうしてそれで規格に反しないのかの観点から説明した。
149(1): (ワッチョイ 8af5-/VPw) 2024/09/14(土)17:01 ID:5H/bnNk90(1/4) AAS
最適化でどうなるかを考えながらC書くくらいならもうアセンブリ書いたほうが良いと思う
150: (ワッチョイ a6e1-865n) 2024/09/14(土)17:07 ID:0gsw2riP0(5/12) AAS
>>146
はちみつは文字列リテラルがアセンブリソースの段階で"hoge"と書かれてなければ消えてると思ってんだなw
例え命令コードの即値で書かれていても消えてる訳じゃないからー!残念!
だから話が噛み合わなかったんだw
まぁ強いて言えば、最適化でデータの表現法方を変えても構わないって言えば良い
151(1): (ワッチョイ a6e1-865n) 2024/09/14(土)17:14 ID:0gsw2riP0(6/12) AAS
x = 1; ← 最適化で消えても構わない
x = 2;
最適化で消えても構わないってこういうことを言うんだよ
char foo[] = "hoge";
"hoge"は消えて良い訳ないだろw
gccは実際、命令コードに文字列を埋め込んでスタックに生成してるが、その文字列はポインター変数を使えば参照可能だ
152: はちみつ餃子◆8X2XSCHEME (ワッチョイ 7932-IU9Y) 2024/09/14(土)17:26 ID:N2YvcTj50(9/14) AAS
>>149
それはそう。 原則としては言語の理屈に従っておくのが良い。
繰り返すけど、少なくとも初心者に対して低レイヤの観点で C を説明するのは筋が悪いと思う。
153(1): はちみつ餃子◆8X2XSCHEME (ワッチョイ 7932-IU9Y) 2024/09/14(土)17:33 ID:N2YvcTj50(10/14) AAS
>>151
> 参照可能だ
その時参照してるのはスタック上にある配列であって、文字列リテラルではないってのを俺は何度書けばいいんだ?
文字列リテラルは本来は「プログラムの開始から終わりまでの寿命を持つオブジェクト」としてあらねばならないのが、
実際には文字列リテラルではない形になってることを「消えてる」と表現したのは確かに微妙な表現だったかもしれないが、
有るべき場所から消えてるんだからそんくらいわかるだろ。
そもそも最初は char* foo = "hoge"; との対比で言ってたんだから。
154(3): (ワッチョイ 8a56-/VPw) 2024/09/14(土)18:13 ID:5H/bnNk90(2/4) AAS
はちみつ餃子の説明はたぶん、C++ の考え方が混ざっていないか
C で配列の初期化子に文字列リテラルが書けるのはあくまで文字列リテラル限定であって、それは式として扱われるのではなく、lvalue も rvalue もクソもないということだと思うが
155(1): はちみつ餃子◆8X2XSCHEME (ワッチョイ 7932-IU9Y) 2024/09/14(土)18:35 ID:N2YvcTj50(11/14) AAS
>>154
初期化子の文法の一部であって式の規則の適用範囲外じゃないの?ってことだよね?
6.7.8 を見てこの場合でも式だと解釈してるけど、そういわれたらちょっと自信がないかも。
156: (ワッチョイ a6e1-865n) 2024/09/14(土)18:53 ID:0gsw2riP0(7/12) AAS
>>153
その配列に格納されているデータが文字列リテラルから生成された文字列(の実体)だろ
厳密に言いたいなら、文字列リテラルはコンパイル時に存在さえしてれば良いものなんだよ
何しろ「リテラル」だから
それを生存期間だの実行時の実体とごっちゃにしてるから訳分かんないことになんだよ
コンパイル時にさえ存在してれば良いという事を実行時には消えてても良いとか言っちゃってんでしょ?
157: (ワッチョイ a6e1-865n) 2024/09/14(土)19:03 ID:0gsw2riP0(8/12) AAS
char foo[] = { 'h', 'o', 'g', 'e', 0 };
文字列リテラルは↑のシンタックスシュガーだ
初期化子は消えても構わないのか?
初期化子が生成した文字列は参照出来ないと言うのか?
158(2): (ワッチョイ 8a56-/VPw) 2024/09/14(土)19:10 ID:5H/bnNk90(3/4) AAS
>>155
外部リンク:en.cppreference.com
ここ参考にしてたから文法定義の時点で式じゃないと思ってたけど、ちゃんと規格上は式としてのパースではあったね、すまない
改めて C99(でいいんだよね、6.7.8 ってことは)の draft 読んでみたけど、文字列リテラルで初期化できるのは 6.7.8.14,15 で特殊に定義された意味論であって、やっぱり式扱いじゃないんじゃないかね
159: はちみつ餃子◆8X2XSCHEME (ワッチョイ 7932-hr+9) 2024/09/14(土)19:58 ID:N2YvcTj50(12/14) AAS
>>154
結果的な挙動からするとどっちでも良いから書いてないだけかも。
160: (ワッチョイ 6663-QZ+t) 2024/09/14(土)20:16 ID:8t7wdnSS0(3/4) AAS
皆拘らずに使っているのに言うのもあれなんだが
C言語にはC++で言う参照はありません
161: (ワッチョイ a6b2-Z1Qu) 2024/09/14(土)21:01 ID:NQ2pFzob0(1) AAS
hogeは破棄されないって一人がんばってるID:0gsw2riP0を救済して差し上げたいが……自分も完全にわかってないのでできない。
162: (ワッチョイ 65cd-RtM0) 2024/09/14(土)21:04 ID:tDLmxNl+0(1) AAS
実在するのはfoo[]だけで
文字列"hoge"は破壊どころか最初からあっても無くてもいいというのがここまでにわかったことだろ
163(3): (ワッチョイ 7910-VVra) 2024/09/14(土)22:15 ID:zMI9sEnq0(1) AAS
配列と別に文字列もどこか別に確保しといて何の意味があるんだよ
この形で配列作る度に二倍メモリ食うことになるじゃないか
164: はちみつ餃子◆8X2XSCHEME (ワッチョイ 7932-IU9Y) 2024/09/14(土)22:32 ID:N2YvcTj50(13/14) AAS
>>163
せやで。 だから最適化の余地があるという話をしてる。
165: (ワッチョイ 6663-QZ+t) 2024/09/14(土)22:34 ID:8t7wdnSS0(4/4) AAS
ここで最適化の話は混ぜない方が良い
166: (ワッチョイ a6e1-865n) 2024/09/14(土)23:00 ID:0gsw2riP0(9/12) AAS
>>163
clangは配列でも文字列リテラルは残ってるよ
ここって想像だけで語るアホばっかだなw
リテラルはコンパイル時のみに必要
それとは別に実行時にリテラルを実体化した値が存在する
基本的にrvalueだ
でないと当然初期化が出来ない
この値をはちみつは無視して語っている
167(1): (ワッチョイ a6e1-865n) 2024/09/14(土)23:04 ID:0gsw2riP0(10/12) AAS
はちみつはリテラルはコンパイル時にのみ必要な事と、実行時には必要な初期値(rvalue)を最適化で命令コードに埋め込む事を消えたと表現して、ごっちゃにしてるアホ
これが結論
168(1): (ワッチョイ a6e1-865n) 2024/09/14(土)23:11 ID:0gsw2riP0(11/12) AAS
リテラルは参照されないと言ってるのがその証拠
そりゃコンパイル時にのみに必要なその場でデータ構造を表現するリテラルを、実行時に参照出来る訳ないだろw
それが出来るのはコードをデータとして表現してるLisp だけだ
C++のテンプレートでも無理
C++のconstevalなら可能になった
std::formatはそれで実装可能になった
実行時には初期化の為のrvalueが絶対に存在する
169: (ワッチョイ a6e1-865n) 2024/09/14(土)23:13 ID:0gsw2riP0(12/12) AAS
constevalも文字列リテラルを参照可能なのはコンパイル時のみだった…
やっぱり真に実行時に文字列リテラルを参照可能なのはLisp だけだな
170: (ワッチョイ 8a56-/VPw) 2024/09/14(土)23:40 ID:5H/bnNk90(4/4) AAS
>>1 の C17 ドラフトのリンク C++17 のやつじゃん
次スレ立てるならこれに変えといて
外部リンク[pdf]:web.archive.org
171(2): はちみつ餃子◆8X2XSCHEME (ワッチョイ 7932-IU9Y) 2024/09/14(土)23:53 ID:N2YvcTj50(14/14) AAS
>>167
起きていることは >>127 でこれ以上なく具体的に説明されてるんだから改めて厳密に表現しないと理解できないとは思わなかったんだよ。
>>168
文字列リテラルが静的記憶域期間を持つことは 6.4.5 に書かれてる。
実行フェイズに存在するオブジェクトだよ。 (最適化を抜きにして仕様通りに解釈すれば。)
配列の初期化子として現れる文字列リテラルの扱いは微妙かもという話が >>154 >>158 の指摘だが、
記憶域期間についての記述は文脈を指定せず文字列リテラル全部を対象にした記述に見える。
172: (ワッチョイ d7cd-qbvN) 2024/09/15(日)00:57 ID:/wZr5+b/0(1/2) AAS
>>163
そりゃ書き換える場合があるからでしょー
一個しかなかったら関数呼ばれるたびに初期値も書き換わってしまう
なんで悩んでるのこの人?
constつけたら一個ですむだろ多分
173(1): (ワッチョイ ffe1-1pYN) 2024/09/15(日)01:17 ID:STy65/7c0(1/5) AAS
>>171
> 実行フェイズに存在するオブジェクトだよ。
存在してんじゃねーかよ!
これが最適化で消えて良いかの話だよ!
gccの場合は命令コードに埋め込んでるけど、消えてる訳じゃないし、別のポインターから参照可能だ
上下前次1-新書関写板覧索設栞歴
あと 829 レスあります
スレ情報 赤レス抽出 画像レス抽出 歴の未読スレ
ぬこの手 ぬこTOP 0.018s