[過去ログ] C言語なら俺に聞け 163 (1002レス)
1-

このスレッドは過去ログ倉庫に格納されています。
次スレ検索 歴削→次スレ 栞削→次スレ 過去ログメニュー
177
(1): (ワッチョイ 9f56-3vlU) 2024/09/15(日)01:45 ID:hg9QOZOF0(1) AAS
>>171
なんかいろいろ書いたけど最終的には自分もそれで合っていると思う
実用上は正直どこで役に立つのかあまり思いつかないが、規格上どういう建て付けになってるのかはとりあえず理解できたかも
というか、実用上あんまり役に立つわけじゃないから今まで調べもしなかったというか

規格上は「リテラル」は存在せず integer/enumeration/floating/character は定数なんですね
それで定数は記憶域期間を持たない
文字列リテラルは静的記憶域期間を持つ
複合リテラルは関数本体の外か中かに応じて静的/自動記憶域期間を持つ、と

うーんでもなあ
某言語でいきなり &1 とか書けるの知ってたら別に定数にも記憶域期間持たせればいいじゃんとか思っちゃうなあ
とりあえずそうなっているというだけか
178
(1): はちみつ餃子◆8X2XSCHEME (ワッチョイ f732-vU+L) 2024/09/15(日)01:46 ID:B6k8li/O0(2/3) AAS
>>175
> 静的記憶期間というのはスコープの事

ちがう。 記憶域期間はオブジェクトの寿命の区分。
6.2.4 を参照のこと。
寿命の区分が設定されている以上はオブジェクト (メモリ上のどこかにある) のこと。

> 文字列リテラルで生成されたデータは実行時には確実にアクセス可能で、消えてるなんて全くあり得ない

関数 (C のプログラムは関数の集合なので実質的にプログラムの全て) はオブジェクトではない。
私が「消える」と表現したのはこの意識があったからだが、機械語のレベルでどこかには存在するという意味ではそりゃ存在するだろう。
(同じ内容が連続する配列だったらループで書き込むような形にすることもあるかもしれない。)
配列の初期化子としての文字列リテラルは本来あるべき場所 (オブジェクト) から最適化で消えてるし、ポインタで指すことは出来ない。
179: はちみつ餃子◆8X2XSCHEME (ワッチョイ f732-vU+L) 2024/09/15(日)01:53 ID:B6k8li/O0(3/3) AAS
>>177
C++ の右辺値参照も左辺値参照も左辺値なんだよね。
参照を経由したら左辺値になるなら最初からそう出来ないか? と思ったことはある。
180: (ワッチョイ ffe1-1pYN) 2024/09/15(日)01:58 ID:STy65/7c0(4/5) AAS
>>178
> ちがう。 記憶域期間はオブジェクトの寿命の区分。
だからエクステントと書いてんだろ!
もしかして理解出来なかったか?

> 配列の初期化子としての文字列リテラルは本来あるべき場所 (オブジェクト) から最適化で消えてるし
本来あるべき場所(オブジェクト)って何だよ?!
目茶苦茶だなw
これがコンパイラーと実行時に存在すべき値(rvalue)をごっちゃにした成れの果てだなw
181: (ワッチョイ ffe1-1pYN) 2024/09/15(日)02:33 ID:STy65/7c0(5/5) AAS
初期化に使われた(文字列)リテラルが実行時にrvalueになったものに名前を付けるべきだな
これは最適化でも消えることはない(当たり前だが…)
名前がないとまたリテラルは消えるから参照出来ない野郎が発生しかねないw
182
(2): (スッップ Sdbf-2MD7) 2024/09/15(日)12:24 ID:WkBCL5VYd(1) AAS
>>174
>char* foo = "hoge";

>のようなケースではポインタ foo は文字列リテラルを指してる

その表現が間違ってる。
fooは静的記憶域を指してるが正しい。

intptr_t *bar = 0xAABB;
この場合数値リテラルを指すなんて言わんだろ。
183
(1): 警備員[Lv.2][新芽] (ワッチョイ 5707-/vo+) 2024/09/15(日)13:50 ID:krajCak80(1) AAS
>>char* foo = "hoge";
>>
>>のようなケースではポインタ foo は文字列リテラルを指してる

>その表現が間違ってる。
>fooは静的記憶域を指してるが正しい。

彼も文字列リテラルは静的記憶域に置かれると言ってなかったっけ
僕にはこの2つの違いが分からないや
勘違いだったらごめんなさい
184: (ブーイモ MM8f-GITO) 2024/09/15(日)16:04 ID:7leD3hDGM(1) AAS
もっと中身のある話しようぜ
185
(1): (ワッチョイ 9794-z7on) 2024/09/15(日)17:53 ID:V70NGKYC0(1) AAS
>>68
規格に後置++演算子は実数型とポインタ型にしか使えないとあったけどそれの関係じゃないの?
規格でそう決まってるだけの話では?
186: (スプッッ Sd3f-2MD7) 2024/09/15(日)18:13 ID:/tCGodXOd(1) AAS
それだな
187
(1): (ワッチョイ d7cd-qbvN) 2024/09/15(日)21:42 ID:/wZr5+b/0(2/2) AAS
ちなみに
int main(int argc, char *argv[])
と定義しても
argvは++できる
188
(1): (ワッチョイ ff63-y7MN) 2024/09/15(日)23:27 ID:dUpBu3ui0(1) AAS
main の引数だけど、人によって好みがある
*argv[]だったり、 **argvだったり、
さすがにargv[][]はいないと思う
189
(2): はちみつ餃子◆8X2XSCHEME (ワッチョイ f732-vU+L) 2024/09/16(月)08:22 ID:JwEVxA0h0(1/6) AAS
>>185
配列はポインタに型変換される。 だから型は合うんだよ。
変更可能な左辺値でなければならないという制約に違反してる。
190
(1): はちみつ餃子◆8X2XSCHEME (ワッチョイ f732-vU+L) 2024/09/16(月)08:28 ID:JwEVxA0h0(2/6) AAS
>>182-183
静的記憶域期間ってのは静的+記憶域期間なんだよ。 静的記憶域+期間じゃないんだよ。

まあ静的記憶域期間を持つオブジェクトが配置されている場所を静的記憶域と呼んでもカジュアルな場面ではそんなに不自然ではないとは思うけど。
実装上は専用のセクションに配置するのが普通だし。
191
(1): (ワッチョイ 776e-SKTh) 2024/09/16(月)08:30 ID:+a4Swf1f0(1) AAS
ここまでのまとめ

Cは生産性が低い
C使いも生産性が低い
192
(1): (ワッチョイ ff63-y7MN) 2024/09/16(月)10:51 ID:yKwOC4kA0(1/2) AAS
ID:+a4Swf1f0 は、言語に何使おうと生産性が低そう
193: (ワッチョイ ff2a-48Tr) 2024/09/16(月)11:29 ID:0nzerU0W0(1) AAS
>>191,192
生産性など、君ら社畜を計る尺度に過ぎんよ。
芸術家は、時間をかけて1行の美しさを追及するものだ。
194
(1): (ワッチョイ 1751-z7on) 2024/09/16(月)12:43 ID:T6H9+ne50(1/2) AAS
>>189
変更可能な左辺値に配列型は含まれないからそれとは違うん?いつポインタに型変換されてんの?
195
(1): はちみつ餃子◆8X2XSCHEME (ワッチョイ f732-vU+L) 2024/09/16(月)13:26 ID:JwEVxA0h0(3/6) AAS
>>194

6.3.2.1 より
> 左辺値がsizeof演算子のオペランド,単項&演算子のオペランド,又は文字配列を初期化するのに使われる文字列リテラルである場合を除いて,
> 型“〜型の配列”をもつ式は,型“〜型へのポインタ”の式に型変換する。

式として出てくる配列は一部の例外を除けば問答無用で変換されるので ++ のオペランドに配列が出てくるときも変換後のポインタ (rvalue) に対する演算 (実際には出来ないけど) として解釈されるということでいいと思う。
196
(1): (ワッチョイ 1751-z7on) 2024/09/16(月)14:56 ID:T6H9+ne50(2/2) AAS
>>195
配列オブジェクトの先頭の要素で左辺値じゃないって書いてあるな
ということは左辺値の式の中に出てくる配列は左辺値じゃなくなっちゃうということ?
なんでそんな仕様になったんだろうね
197
(2): はちみつ餃子◆8X2XSCHEME (ワッチョイ f732-vU+L) 2024/09/16(月)16:28 ID:JwEVxA0h0(4/6) AAS
>>196
C には配列の要素を指すポインタとは別に配列を指すポインタというものもある。
こんなことが出来る。

int foo[10];
int (*bar)[10] = &foo;

このときの bar の型は int(*)[10] ということになるわけだが……。
型情報として長さが含まれるのはかえって邪魔だ。
大抵の配列を受け取る関数 (str系やmem系など) は配列の大きさが固定ではないから。
配列の先頭要素で配列を代表させる (それが簡単な記法にする) ほうが都合がよかったんじゃないかと思う。
配列全体をひとつの値として扱いたい場合のほうが少ないだろうという判断もそれなりに合理的じゃないかな。

いまどきの言語 (Go とか Rust とか) は範囲を表すスライスという概念を導入して解決してるけど、
C の登場時期だと 2 ワードのオブジェクトを基本型にするのってなんかヤじゃない? と思ったとしても仕方ない。
198: (スプッッ Sd3f-2MD7) 2024/09/16(月)17:22 ID:udznqyd1d(1/2) AAS
>>190
横からすまんが、記憶域期間って言葉も変
199
(1): (スプッッ Sd3f-2MD7) 2024/09/16(月)17:23 ID:udznqyd1d(2/2) AAS
>>189
>配列はポインタに型変換される。

それは関数呼び出しの場合だぞ
200: (ワッチョイ bf79-MnYn) 2024/09/16(月)17:29 ID:E0fXFEgV0(1) AAS
この糞コテは半端知識のかまちょだからNGやスルー推奨
201
(1): はちみつ餃子◆8X2XSCHEME (ワッチョイ f732-6w0d) 2024/09/16(月)18:10 ID:JwEVxA0h0(5/6) AAS
>>199
こっちは根拠になる規格の文面を提示してるんだから違うというなら違うと思う根拠を提示して。
202: (アウアウウー Sa5b-E6+g) 2024/09/16(月)18:57 ID:ISRAyNkZa(1) AAS
>>188
そらargv[][]では誤りだもんな
203
(1): (アウアウエー Sadf-N1Zj) 2024/09/16(月)21:32 ID:NNTpe0yPa(1) AAS
>>187
たしかに関数の引数だと違うんだな
外部リンク:ideone.com
#include <stdio.h>

char *hoge(char fuga[10])
{
++fuga;
return fuga;
}

int main(void) {
char hage[10] = {0};
char *p = hoge(hage);
printf("%p, %p\n", hage, p);
return 0;
}

// もちろん ++hage は出来ない
外部リンク:ideone.com
204: (ワッチョイ bf4f-NiVF) 2024/09/16(月)22:10 ID:hHcIxSUD0(1) AAS
>>197
流石に言ってる事が的外れ過ぎるのでもうちょっと勉強した方がいいと思うよ
205
(1): 警備員[Lv.1][新芽] (ワッチョイ f731-/vo+) 2024/09/16(月)22:25 ID:z+htC2pc0(1/2) AAS
恥ずかしながら、静的記憶域期間(で合ってるのか?)という言葉を知らなくて、ライフタイムは「静的」に含意されているのかと思ったワ…
しかし、記憶域期間って違和感あるなぁ
206: 警備員[Lv.1][新芽] (ワッチョイ f731-/vo+) 2024/09/16(月)22:30 ID:z+htC2pc0(2/2) AAS
わけわからん
>>205は撤回します
1-
あと 796 レスあります
スレ情報 赤レス抽出 画像レス抽出 歴の未読スレ

ぬこの手 ぬこTOP 0.016s