C言語なら俺に聞け 163at TECH
C言語なら俺に聞け 163 - 暇つぶし2ch2:デフォルトの名無しさん (アウアウエー Sa02-hIhh)
24/07/16 23:09:40.55 zAWhziLLa.net
O2

3: 警備員[Lv.4][新芽] (ワッチョイ 5a73-fQmy)
24/07/17 00:38:03.50 x2xsFX7F0.net
"甲乙丙丁"[1];

4:デフォルトの名無しさん (ワッチョイ b132-HYxY)
24/07/17 02:16:43.37 rcKIBlXh0.net
C23 最新ドラフト
URLリンク(www.open-std.org)

5:デフォルトの名無しさん (スプッッ Sda5-cSaw)
24/07/19 12:09:58.52 7xb1gIFBd


6:.net



7:デフォルトの名無しさん (ワッチョイ be2d-Xdjv)
24/08/13 10:33:10.70 0tpsfiHy0.net
C99以降のC言語では、main関数が正常に終了した場合、
明示的にreturn 0;を記述しなくても、コンパイラが自動的にreturn 0;を
挿入することが規定されています。
これにより、main関数の最後にreturn文を省略することが可能になりました。

これまじ?
いや省略できるのは知ってたけど
書かなくても言語仕様的に正しいってことなのでは

8:デフォルトの名無しさん (ワッチョイ 2e2a-Fna2)
24/08/13 10:54:13.55 rWI8dcbL0.net
>>6
> 省略できる

これまじ? ってやってみたら省略できた。知らんかった。

9:デフォルトの名無しさん (ワッチョイ c25c-PXPr)
24/08/13 11:02:03.46 zgXpATPx0.net
C++の方は最初からそうじゃなかったっけ?

10:デフォルトの名無しさん (ワッチョイ 2e63-mJNK)
24/08/13 11:04:04.36 iZOfVN0Y0.net
ところで、main以外はどうなんだろう
mainだけ特別って事なのかな?OSとも絡むし

11:はちみつ餃子
24/08/13 11:58:17.89 ZDyvNux60.net
>>9
retunr 0; が補われるルールは main だけの特別扱いだけど……。
関連する変な規則として C では関数の返却値の型が void ではないときに return せずに } に到達、かつ、関数の呼び出し元が値を使おうとするのは未定義ということになってる。
逆に言えば } に到達するだけなら OK ってことね。
C++ だと関数の返却値の型が void でないときに return せずに } に到達するだけで駄目という違いがある。

12:デフォルトの名無しさん
24/08/13 20:38:38.66 Yor/eSuX0.net
>>9
値を返さない関数ならreturnは省略できる
値を返す関数だと戻り値が不定になる
(多分コンパイルでwarningが出るか最近のではerrorになるだろうな)
そのくらい一度も試したことないのか?

13:デフォルトの名無しさん
24/08/14 08:45:20.95 92pG5tQ9a.net
CPUが最後に処理したアキュムレータの内容が
戻り値として有効になってるケースが多い
違う実装があったら教えてくれ

14:デフォルトの名無しさん
24/08/14 09:29:38.29 o5Tm+MCf0.net
戻さないで自動的に挿入されるのならvoidでいいやん

15:デフォルトの名無しさん
24/08/14 16:14:28.35 91FNum+40.net
>>12
CPUでも最適化レベルでも変わるのでその情報は無意味だ
素直にvoidにしとけばいいじゃん

16:デフォルトの名無しさん
24/08/17 12:40:14.00 P2kCpMMm0.net
>>12
じゃあお前に教えるために
これからそういうの作ろう

17:はちみつ餃子
24/08/17 17:19:02.88 w43wc/GB0.net
>>12
最適化が絡むとなんでも起こる。
GCC でやってみた。
URLリンク(godbolt.org)
インライン化と合わさったときはおそらく
「なんでもいいなら事前に適当な定数 (この場合はゼロ) に置き換えてええやろ」ということが起こってる。
インライン化を抑止したらそのときに入ってたでたらめな値になる。

18:デフォルトの名無しさん
24/08/18 12:47:05.86 z2E2wJpW0.net
CGCのサイクル
URLリンク(www.cgcjapan.co.jp)

19:デフォルトの名無しさん
24/08/19 14:50:35.14 2a6IfSVu0.net
CCG
URLリンク(dic.pixiv.net)

20:デフォルトの名無しさん
24/08/19 15:05:46.71 V1kjWLO50.net
アキュムレータって呼び名、いかにも電卓っぽい

21:デフォルトの名無しさん
24/08/26 18:48:30.29 cPELMU3ld.net
ヘッダファイルちゃんとincludeしようよ。

22:デフォルトの名無しさん
24/08/26 19:32:21.98 0fQF2fer0.net
ヘッダーファイルインクルードする1行だけのプログラム見たことがある
#include /dev/tty

23:デフォルトの名無しさん
24/08/27 00:49:35.29 9npsKRkS0.net
それヘッダファイルじゃないです

24:デフォルトの名無しさん
24/08/27 08:24:35.00 apM/pcD70.net
エラー: #include は "FILENAME" または <FILENAME> が必要です

25:デフォルトの名無しさん
24/08/27 14:09:22.45 oHcafaf7a.net
<>を入力すると消えるブラウザというか掲示板も流行ったなHTMLは糞だわ

26:デフォルトの名無しさん
24/08/27 17:58:59.59 K+iNaUMP0.net
大抵最初の開発者は誰かが修正してくれるだろうと適当な仕様で設計して、
その後引き継いだ開発者はなにか意図があるのだろうと思ってそのまま維持していくという悪循環・・・。

27:デフォルトの名無しさん
24/08/28 01:09:19.85 E82+IHOF0.net
>>25
あるある過ぎる

28:デフォルトの名無しさん
24/08/28 01:32:44.54 ZIniGH7S0.net
ちち、どっかいけ

29:デフォルトの名無しさん
24/08/28 01:35:08.84 ZIniGH7S0.net
ごばくした、ごめん

30:デフォルトの名無しさん
24/08/28 09:35:19.18 22YTSKRT0.net
アーニャにはここはまだ早い

31:デフォルトの名無しさん (オイコラミネオ MM1b-qpqo)
24/09/02 15:52:36.13 VEiLzJptM.net
RustがCより速くなるベンチマークは見たことがない

Nim2.0のORCは明示的にオブジェクトプールを使ったプログラミングが必要ですが
ベンチマークがCより2倍以上速くなって、特にハードなリアルタイムシステム向け
のチューニングもできるようになってるみたい
URLリンク(zenn.dev)

Nim2.0がCより2倍以上速くなって、しかもORCでメモリ安全も担保されているなら
Rustを使う意味がなくなると思うのですが、このベンチマークは本当なのでしょうか?

NimはCのソースコード吐けるからから、Nimの手動メモリ管理はCの手動メモリ管理と
同じとして、Nim2.0のORCで明示的にオブジェクトプールを使ったプログラミングと
比較した場合のベンチマークが2倍以上速くなってるからCより速いと言ってる
URLリンク(github.com)

人間がCの手動メモリ管理したプログラムだと限界があるNimのムーブセマンティクスの
アルゴリズムでメモリの最適化をしてるから、人間では到底太刀打ちできない事を証明
した論文があるオブジェクトプール版のNimから生成したCのコードは人間には書けない

Nim2.0のムーブセマンティクスの本当に優れた最適化とORCで明示的にオブジェクトプールでプログラミングすることによって、人間がCの手動メモリ管理したベンチマークより2倍以上速くできる
URLリンク(zenn.dev)

32:デフォルトの名無しさん (ワッチョイ 0701-gNE8)
24/09/02 22:08:58.52 DccWFR9v0.net
Rustを褒めて自尊心保つやつの次はNim版が出てきたのか

33:デフォルトの名無しさん
24/09/02 23:12:40.71 3HuFqT9S0.net
Nim推しは以前から変なやつ多かったから

34:デフォルトの名無しさん
24/09/02 23:28:27.10 09ZYUS090.net
Nim言語の良し悪しは分からんが、メモリ管理に関しては理想的だわ
ムーブ後のオブジェクトにアクセスするとRustだとコンパイルエラーで面倒な事になるけど、Nimは参照カウントを使って解決するので少し遅くなるだけだ
そっちの方が絶対良い
気になる場合は後で直せる

35:デフォルトの名無しさん
24/09/03 18:51:27.81 xAVNzrUq0.net
>>33
コンパイルエラー?

36:デフォルトの名無しさん
24/09/04 01:03:52.03 c5l8yfTZ0.net
>>34
だからなんだ?
Rustでムーブ後のオブジェクトにアクセスしてみろよ

37:デフォルトの名無しさん
24/09/04 09:34:28.92 eBGcFHFx0.net
>>33
どこにコンパイル時期にメモリの不正アクセス検知できるコンパイラーがあるんだよ
便利すぎないか

38:デフォルトの名無しさん
24/09/04 09:42:59.71 uvDwCGK/0.net
>>36
ムーブ(所有権の移動)の概念知らない奴かよw

39:デフォルトの名無しさん
24/09/04 11:20:54.96 yycwJMQK0.net
時代に取り残されたじじい

40:デフォルトの名無しさん
24/09/04 11:26:12.60 6FkHz3Id0.net
今どきのヤングはどの辺を走っているのかな?

41:デフォルトの名無しさん
24/09/05 00:07:48.49 /oUqYYg3a.net
RefCellのborrowとかborrow_mutがCより速い訳がないだろ

42:デフォルトの名無しさん (ワッチョイ c770-bfwh)
24/09/05 06:20:13.32 IMzSmyWL0.net
アセンブラ使ったことない子供たちにはわからんのだろ

43:デフォルトの名無しさん
24/09/05 08:53:17.49 oYH6V42M0.net
Aiの時代にこんなレトロ言語に夢中になってる場合でもないだろ

44:デフォルトの名無しさん
24/09/05 09:42:51.26 00qJ+IF20.net
ペイントソフト溢れた時代にエクセルで描いて絶賛される時代。

45:デフォルトの名無しさん
24/09/05 13:27:55.60 IMzSmyWL0.net
AIなんて究極的には予備知識なしで使えるようになるもんだろ
いま必死で呪文を覚えてる奴らには気の毒だがw
プログラムの学習はそれとは逆だぞ

46:デフォルトの名無しさん
24/09/05 13:41:12.34 YoL+MCk60.net
AIにはアセンブラかCで書かせた方が効率がいいじゃん

47:デフォルトの名無しさん
24/09/05 20:45:06.75 mduO1G690.net
今はアニメもCGで作る時代だけど、だからデッサン力なんて不要と言ってるのに近いなw

48:デフォルトの名無しさん
24/09/06 02:12:25.16 ObPC8Kit0.net
AIなら直接機械語書けそうだけど最低限人間がコードを読めるようにするためにCで出力するのが流行りそう

49:デフォルトの名無しさん
24/09/06 17:06:00.74 3sxDLHxZ0.net
もはやプログラマはAIにどう質問するかだけが求められてる時代
ビックデータが前提なのはわかってるけどchatAIと画像AIはマジでオーパーツだわとても0と1だけで実現されてる技術と思えん・・・

50:デフォルトの名無しさん
24/09/06 17:30:18.67 bUa4C6AFM.net
ここはAIの質問スレになる予定です

51:デフォルトの名無しさん
24/09/06 17:59:38.15 wWap9ofG0.net
>>48
Cやアセンブラを知らなかったらコンピューター自体が魔法に思えるんだろうなw

52:デフォルトの名無しさん
24/09/06 18:14:44.45 fzo/g0jk0.net
プログラム上での比較が、未だに変数2つの比較(if(A=B)とか )しかイメージ出来ないので
AIのアルゴリズムどころか、2つのサイズの違う画像比較ってのさえどうやるのか検討もつかん・・・。

53:デフォルトの名無しさん
24/09/06 18:37:17.18 4wqfzUPa0.net
3Blue1BrownJapanのディープラー


54:ニング解説動画 https://www.youtube.com/watch?v=tc8RTtwvd5U 現在chapter6まで和訳されてる(本家英語版は7が出た)



55:デフォルトの名無しさん
24/09/06 21:13:32.20 wWap9ofG0.net
>>51
引き算してその絶対値が一定以内だったら同じとみなす
if(abs(A-B)<C){…
それぐらいならわかるだろ?

56:デフォルトの名無しさん
24/09/06 21:19:53.07 eMGejp5m0.net
点でしか見れない人に面を理解させる手法・・・

57:デフォルトの名無しさん (ワッチョイ 274e-XcdZ)
24/09/06 21:46:42.59 ObPC8Kit0.net
この世界もほぼ陽子と中性子と電子だけで出来てるのにこれだけ複雑なんだから0と1だけで複雑な演算出来ても不思議ではない

58:デフォルトの名無しさん (ワッチョイ 5fad-WCFq)
24/09/06 21:53:29.16 H8MSdYGz0.net
ようこちゃんとでんこちゃんは知っているけど
中性子って子は知らない

59:デフォルトの名無しさん
24/09/06 22:09:25.96 aKdHJjI6M.net
光子ちゃんも忘れないであげて

60:デフォルトの名無しさん
24/09/07 00:47:09.38 mFTEs+Pq0.net
0と1だけじゃないけどな
その他に位(くらい)という概念がある
これによって無限の数を表現できる
むしろ位の概念によって数が表現されている
それさえ有れば記号なんて何でもいい

61:デフォルトの名無しさん
24/09/07 20:51:59.47 XGt+Z3l/0.net
どこかの国だか村では両手の指の数以上を表現する言葉がないって話をどこかで・・・。

62:デフォルトの名無しさん
24/09/07 22:06:43.98 GNvzZpYIM.net
ムカデは100進数で数えている

63:デフォルトの名無しさん
24/09/08 00:25:53.15 zd6RlSMM0.net
>>59
位の概念が無いから10までしか数えられない
位を考慮すると両手で1023まで数えられる

64:デフォルトの名無しさん
24/09/08 00:30:46.43 zd6RlSMM0.net
指を曲げる伸ばすの2通りとすると1023だが、指を完全に曲げる、伸ばす、半分まで伸ばす(曲げる)の3通りとすると3^10-1=59,048まで表現できるなw

65:デフォルトの名無しさん
24/09/08 07:38:58.99 LXYiwE7e0.net
>>60
ヒトを含めた四肢類は4進法なの?

66:デフォルトの名無しさん (ワッチョイ bd5f-FAeb)
24/09/08 10:08:59.05 mVbg4wOX0.net
>>61-62
人差し指と薬指を伸ばして、かつ中指と小指を曲げるのは難易度がやや高いぜ。
(親指を伸ばせば『グワシ』)

67:デフォルトの名無しさん
24/09/08 10:25:56.18 IhFVsGpe0.net
グワシは古語

68:デフォルトの名無しさん
24/09/08 15:41:04.82 aTNFTtUw0.net
とりあえず、他人の投稿で言ってもいない単語や解釈を勝手に加えてマウント取ろうとするのはどうかと思うぞ。

69:デフォルトの名無しさん
24/09/08 23:23:27.00 6gnZvy5A0.net
問題はギャグとしてつまらないという点だ

70:デフォルトの名無しさん
24/09/09 17:06:32.51 ft14UVke0.net
lvalueに関してエラーが出るんだけど、どうしてこれがだめなのかわからないです
#include <stdio.h>
int main()
{
char s[] = "hoge";
char t[100];
while (*t++ = *s++)
;
printf("%s", t);
}

71:デフォルトの名無しさん
24/09/09 17:17:50.19 JnQxQHVK0.net
>>68
 char *p = s;
 char *q = t;
 while (*q++ = *p++)
こう書けば通る。何故かはちょっと考えて ;

72:はちみつ餃子
24/09/09 17:19:13.64 XH4OT6yj0.net
>>68
s の型は char[5] 、 t の型は char[100] だというのはわかる?
だけど式に出てく


73:る配列は原則として配列の先頭要素を指すポインタ (この場合に型でいえば char*) に型変換される。 変換後に出てくるポインタは rvalue なのでインクリメントの対象に出来ない。 rvalue ってのは式の評価をする間に一時的に生まれて評価が終わったら消えるものなので 仮にインクリメント出来たとしても何にも使えない。 配列が勝手にポインタに変換されるっていうのが変則的で分かり難いポイントだけど これは C を使ってたら避けようがない。



74:デフォルトの名無しさん
24/09/09 18:22:38.82 zvC05GrM0.net
ポインタと同じ表記が使えるだけでポインタに変換されるわけではないぞ老害

75:デフォルトの名無しさん
24/09/09 18:25:50.23 JnQxQHVK0.net
 char *s = "hoge";
 char t[100];
 int i = 0;
 while (*(t+i) = *s++)
  i++;
sを配列ではなく、ポインタに変える、
tもポインタにしたいところだが、格納先確保が目的なら
先頭アドレスからのオフセット指定で格納する様に変更

76:デフォルトの名無しさん
24/09/09 18:30:55.08 D7I9z5W00.net
それなら while (*(t+i) = *(s+i)) って書くかな

77:デフォルトの名無しさん
24/09/09 18:36:50.90 JnQxQHVK0.net
s[]、t[100]と書いたとき、sやtはメモリー上の特定の位置を指す
ラベルのようなものなので書き換える事は出来ない。ポインタ定数とも言う。
一方ポインタ変数は、任意のアドレスを指す変数、変更も操作できる
constとか、突っ込まんでください

78:はちみつ餃子
24/09/09 18:57:03.60 XH4OT6yj0.net
>>71
規格には「型変換する」と明瞭に書いてあって変換しないと解釈できる余地はない。

79:68
24/09/10 07:06:02.36 fwzKZR690.net
色々教えてくれてありがとう
s[]の先頭を指すポインタ*sを++で進めることができちゃったら
s[0]もズレちゃうのでだめだってことだよね
そりゃだめだわ

80:デフォルトの名無しさん
24/09/10 07:45:50.17 ZXVJVLjy0.net
s[], t[100]; って宣言したなら、s[idx], t[idx] って使おうよ

81:デフォルトの名無しさん
24/09/10 08:09:53.27 oAzej4EH0.net
そこはこだわらんでもいいだろ

82: 警備員[Lv.5][新芽] (ワッチョイ f969-ztXh)
24/09/10 09:09:59.70 H8O84G940.net
sやtは constということでもないのか

83:デフォルトの名無しさん
24/09/10 10:14:17.88 WwqiNfks0.net
立て札は移動禁止です

84:デフォルトの名無しさん
24/09/10 13:19:09.36 KGjTz1X0a.net
>sやtは const
constっていつからあったか知らんけど
constない頃からsもtも*pや*qとは扱いが違ったんじゃね

85:はちみつ餃子
24/09/10 14:04:37.40 rqI1GpSt0.net
lvalue の概念は K&R 1st の頃からあったよ。
lvalue という用語はちょっとどうなの……と思うけど。
Rust だと place と呼んでるみたいだね。

86:デフォルトの名無しさん
24/09/10 21:10:52.20 UL+jlunn0.net
お前は変な事ばかり言ってるからもう引っ込んどけよ

87:デフォルトの名無しさん
24/09/10 21:22:40.00 OwUxLa4s0.net
ポインタそのものを変えないやつと
指す先を変えないやつの書き方で
未だに迷うっていう

88:はちみつ餃子
24/09/10 21:35:00.77 rqI1GpSt0.net
キーワードを並べる順序で意味が変わるのは迷うけど
順序をどうならべても良い場合もそれはそれでびっくりする。
int const long foo;
みたいに変数を宣言して良い。
まあそんなことをするやつはいないと思うけど。

89:デフォルトの名無しさん
24/09/10 22:53:26.23 BKdRZcpD0.net
consr char*は本当はchar const*と書くべきなんだよね
これでもコンパイルは通って同じ結果になる
読む時は右から読めばいい
pointer to const char
これだと指す先がconstなのが分かりやすい
ポインター自体をconstにするには
char* constとして、同じく右からconst pointer to charと読む
両方constは
char const* const
となるけど、最初のconstは左に書けるので
const char* const
とも書ける
これが分かれば迷う事は無くなる

90:デフォルトの名無しさん (ワッチョイ a6b2-Z1Qu)
24/09/11 01:20:44.10 ZbZmMQbl0.net
それ前橋氏のポインタ完全制覇で知った

91:デフォルトの名無しさん
24/09/11 08:00:07.84 eq6A6T9x0.net
>>81
アセンブラにして考えるとわかりやすい
char s[] = "hoge";
アセンブラの表現↓
s:
   .db "hoge¥0"

char *s = "hoge";
アセンブラの表現↓
s_org:
   .db "hoge¥0"
s:
   .dw s_org

上の場合書き換えようにもsには実体がない
アドレス定義ラベルでしかない
*ただし完全に最適化されると下も上と同じになる
   

92:
24/09/11 09:16:47.77 IhX3t9qv0.net
ここでいう sには実体がない、とはどういうことですか?

93:はちみつ餃子
24/09/11 09:19:23.27 Zm39E+090.net
大元の質問が >>68 なので低レイヤからの説明はあまり筋が良くないと思う。
エラーメッセージの意味を読み取れるようにならないから。

94:デフォルトの名無しさん
24/09/11 09:30:46.32 dQ20XCdF0.net
8ビットCPUのメモリ保護されてない頃だと
配列どころか、プログラムコードも書換できました笑

95:デフォルトの名無しさん
24/09/11 09:49:35.14 h52e7Ahm0.net
> sには実体がない、とはどういうことですか?
変数エリアに書き込まれていない数値、データ。
プログラム上で要求された時にコンパイル時や関数によってその都度作られる仕様・・・かな?しらんけど。
>91
>プログラムコードも書換できました
それはむしろ”技術”扱いだったな。
サブルーチンでジャンプ先やIOポートを書き換えて・・・て。
昔はCPU等のバグ利用がテクニックだったけど、今じゃバグの温床、セキュリティホール扱いだね。

96:デフォルトの名無しさん
24/09/11 15:02:12.18 DEx1pDDa0.net
こんだけいて>>77くらいしかまともな回答者がいないとかひどいなあ

97:デフォルトの名無しさん
24/09/11 15:25:16.11 1n/VD1trM.net
そんなのこだわっても結局関数の引数で配列型では渡せないんだからその程度は受け入れて慣れたほうがいい

98:デフォルトの名無しさん
24/09/11 15:58:54.52 dQ20XCdF0.net
ここは、「聞け」とはあるが、「回答する」とは書いていない

99:デフォルトの名無しさん
24/09/11 16:44:23.62 +qxKgs2P0.net
こっちが自然だろ
t[100]を*(t+idx)なんてやる方が何の拘りだよ

100:デフォルトの名無しさん
24/09/11 16:55:25.58 tx1pt4w10.net
その程度どっちでもいい

101:
24/09/11 20:45:08.11 l6JSnCmY0.net
配列は外部リンケージのときも注意が必要なんだよね
あまりそういう使い方しないから、すぐにはピンとこないや

102:デフォルトの名無しさん
24/09/11 22:04:51.93 +V4MmH6p0.net
>>93
別にまともでもない
配列で定義してポインタで操作できるのがCの柔軟性だから
idxにこだわると簡単な操作を複雑にしかねない

103:デフォルトの名無しさん
24/09/11 23:11:00.81 dQ20XCdF0.net
> while (*(t+i) = *s++)
これは、
> while (*t++ = *s++)
;これがエラーになるのは何故かと言う質問から始まったからです
t++がエラーで、t+iなら大丈夫が理解できれば解決だと思う
ポインタの理解というのは壁にはなりますが、
乗り越えれば意外と簡単です、がんばれ!

104:
24/09/12 00:58:15.86 QGeKjVfA0.net
>>92 ありがとうございました(sには実態がない)
gcc -S test.c
で .s を出力して眺めてみると、そのような感じになっていました
最適化と、AT&Tのオペランドが逆なのに慣れず読みにくかったですが
"hoge" は「実体」が .data に置かれ、実行時にスタックにコピーされるのかと想像してましたが、実装がどうあれ、スタッフ上に "hoge" を置くための元を実体というのは違うと思いました
実際、"hoge" は .db でアロケートされず、4字は 32ビットの数値定数とされ、スタックに即値で転記されていました(実行時に生成されていました)
# とても伝わりにくいと思いますが…

105:はちみつ餃子
24/09/12 08:54:43.60 TbaO6N6i0.net
誰も説明してなかったことに気づいた。
E1[E2] が (*((E1)+(E2))) と等価であるというルールがある。

106:デフォルトの名無しさん
24/09/12 21:59:57.92 m7IlJoP80.net
それいにしえからのバカ発見器なんだが2024年になってもまだ動いてるとはC言語おそるべし

107:
24/09/12 23:41:05.77 +nQe2m720.net
次の方どうぞ

108:デフォルトの名無しさん
24/09/12 23:43:09.62 sEtsUeoh0.net
>>103
その自由度があるからC++でhtbl["key"]の様な事が出来る
Cじゃ意味ない仕様だけど、禁止する必要も無かろう

109:デフォルトの名無しさん
24/09/13 08:23:17.89 ykZRrldI0.net
>>101
"hoge"は長さちょうど32ビットだから即値でスタックに書き込むようになってるということなら
最適化によってそこまで省略されてるわけでsに実体がない件とはあまり関係ないな
最適化オフにするかもっと長い文字列で実験してみては

110:
24/09/13 09:12:47.27 cjEIJ97r0.net
>>106
ありがとうございます
もう少し正確に書けばよかったのですが、4字と '\0' の2回に分けて転記していました
また、hogeを長くして(10字くらい?)試すと、やはり 4字ずつ整数にパックして即値で転記していました
もっと長大な文字列試せば、別にアロケートされたそれをコピーするコードが吐かれたかもしれませんが、>>92 の指摘通り、実体がなく実行時に生成されることを確認できたとして打ち切ってしまいました

111:はちみつ餃子 ◆8X2XSCHEME (ワッチョイ 65e8-hr+9)
24/09/13 10:12:57.71 9XTDQHQm0.net
C の仕様は抽象機械の動作として記述される。
抽象機械の動作をどのように実際の機械と対応させるかは自由で、見かけ上の動作が同じならどういう機械語になってもいい。
生成された機械語から言語仕様を理解しようとすべきではないよ。

低レイヤプログラミングするならどう対応付くか知る必要がある場合もあるのは否定しないけど……

112:デフォルトの名無しさん (ブーイモ MM45-bJfQ)
24/09/13 10:23:10.52 OBSQyTYbM.net
その抽象機械の定義はしょせん後付け
c言語のソースから生成されるマシン語の想像が付くようになるのはいいこと

113:デフォルトの名無しさん (ワッチョイ 6663-QZ+t)
24/09/13 10:25:26.12 y2ap91b60.net
C言語ハンドコンパイラ

114:はちみつ餃子
24/09/13 11:25:36.89 9XTDQHQm0.net
>>109
機械語の想像がつくのが不要とも悪いとも言ってないよ。
そこから言語仕様を理解しようとすべきじゃないと述べてる。
できないから。

115:デフォルトの名無しさん
24/09/13 11:46:29.60 HT/On1VB0.net
所詮部外者の推測。

116:デフォルトの名無しさん
24/09/13 12:46:10.11 CiewPVvpM.net
今日は患者が多いですね

117:デフォルトの名無しさん
24/09/13 12:53:56.59 OBSQyTYbM.net
>>111
無用な心配
Xに溢れてるクソリプと同じ

118:
24/09/13 13:50:08.30 cjEIJ97r0.net
>>108
ありがとうございます
そもそも >>88 で sの実体がないとはどういうことか、というのが疑問だったためで、言語の仕様(というか実装)がどうかには着目していませんでした
printf("%s\n", s); が .sではputs(s); に置き換えられていたり
そうだよな~

119:
24/09/13 13:59:45.58 cjEIJ97r0.net
あー、実装には注目してるのか>自分

120:はちみつ餃子 ◆8X2XSCHEME (ワッチョイ 7932-hr+9)
24/09/13 14:32:38.41 7dvxgxgq0.net
この場合に限っては言語仕様としての理屈もあんまり違わんけどな。
ただ、正式な用語を知ってると細かいことを調べやすいみたいなのはあるので便利。

121:デフォルトの名無しさん
24/09/13 16:10:44.34 HymUJJD5H.net
gccは配列に確保した短い文字列は最適化無しでもレジスターに載せてしまってるな
ポインター文字列は最適化してもレジスターには載らない
なので配列は配列として使った方が最適化で高速化される可能性があるという事だな

122:はちみつ餃子
24/09/13 16:26:39.79 7dvxgxgq0.net
ポインター文字列って変な言葉だな。
この場の造語だと思うけど
char *foo = "bar";
みたいなやつのことだよね?
文字列リテラルは静的記憶域期間 (寿命はプログラムの最初から最後まで) を持つオブジェクト。
どこかにある文字列をポインタで指しているという状況。
そのどこかにある文字は他のどこかから指し示されることもありうるので簡単には消えられない。
その一方で、配列の初期化子は配列を初期化する以外に使われる可能性がない。

123:デフォルトの名無しさん
24/09/13 16:36:31.22 bblj+c3pa.net
>>93
それのどこがマトモなんだよ
>>94 の言い分の方が正しい
配列型が無いんだから

124:デフォルトの名無しさん
24/09/13 16:38:54.03 bblj+c3pa.net
>>96
>t[100]を*(t+idx)
t[100]を100[t]
よりはマシ
>>97
だよな

125:デフォルトの名無しさん
24/09/13 17:26:56.71 HymUJJD5H.net
>>119
んなこたーない
char foo[] = "hoge";
char* bar = &foo[1]; /* 敢えてずらしてみる */
printf("bar -> %s\n", bar);
で中身は何度も参照されるぞ
gccで試してみたら敢えてずらしてポインターに代入されたとしても、レジスターに文字列を保持したままprintfに渡すというトリッキーなコードが生成されたw
スタックに文字列を書き込んでそのアドレスを渡してるっぽい

126:デフォルトの名無しさん
24/09/13 17:45:50.36 HymUJJD5H.net
短い配列文字列をポインターに代入したらレジスターに保持する最適化を諦めるかと思ったら、そうじゃなくて意地でもレジスターに保持したまま処理を進めるgccスゲーよw
clangの場合はポインターも配列も常に静的に文字列を定義したものを使ってた

127:デフォルトの名無しさん
24/09/13 18:12:32.57 y2ap91b60.net
最近のCPUはレジスターに文字列格納できるんだな
何バイトくらいなら入るんだろうか

128:デフォルトの名無しさん
24/09/13 18:26:19.17 HymUJJD5H.net
gccの場合だと64bitだと8バイトだから最大7文字かなと思ったらレジスターを複数使ってでも載せようとしてたw
取り敢えず50文字まで試したけど全部レジスタに載ってた
でもこの辺はレジスタの空き具合にもよるのか?詳しくは分からん

129:デフォルトの名無しさん
24/09/13 18:41:27.03 y2ap91b60.net
何か執念みたいなのを感じました笑

130:デフォルトの名無しさん
24/09/13 18:50:06.89 HymUJJD5H.net
スマン…間違えた…orz
正確にはアセンブリコードに書かれてると言うべきだった
movabsq $3833745473465760056, %rdx
movabsq $3978425819141910832, %rax
movq %rdx, 40(%rsp)
movabsq $3544395820347831604, %rdx
movq %rdx, 56(%rsp)
↑こんな感じで文字列が直値で表現されてて、スタックに積んで使ってた
だったら静的に確保した方が速い気がするけど、やっぱりレジスターから直接使う事が有るのか?
取り敢えずコンパイラーが出力するコードに深入りしない方が良いって事は分かったw

131:はちみつ餃子
24/09/13 18:59:17.17 7dvxgxgq0.net
>>122
その場合に参照されるのは foo であって、 "hoge" というリテラルではない。
"hoge" は foo を初期化する以外の用途に使われていない。

132:デフォルトの名無しさん
24/09/13 20:11:25.22 ykZRrldI0.net
>>127
データセグメントに確保するよりも
コードセグメントに書いたほうがすでにキャッシュに載ってるから高速なのかもな

133:
24/09/13 20:41:46.32 cjEIJ97r0.net
速度の最適化か、生成されるオブジェクトの小ささかのトレードオフなんだろうね
テスト用のコードは小さいから、後者は気にせずゴリゴリやってるのかな…

134:デフォルトの名無しさん
24/09/13 23:38:57.27 uRdGeQ4y0.net
世の中CやめてRustにしろだとか
OpenAIの新AIが競プロで上位1割のプログラマに匹敵とか言うじゃない
今更人間がCを続ける意義ってなんなんだろう

135:デフォルトの名無しさん
24/09/14 00:03:48.69 UIMFiyQN0.net
COBOLみたくロストテクノロジーを理解出来る貴重な人になれる

136:はちみつ餃子
24/09/14 00:19:19.91 N2YvcTj50.net
低レイヤに関わる資料が C を前提に書かれていたりするのは普通のことなのでたとえ C でプログラミングしなくてもある程度は身に付いてないと困ることはあるだろう。

137:デフォルトの名無しさん
24/09/14 00:39:08.66 0gsw2riP0.net
>>128
初期化する以外に参照されてないってのはおかしいだろ
printfで中身が表示されてんだから
ポインター変数のbar経由で中身を参照してるけど、中身は初期化で渡された文字列そのものだ
そもそもリテラルが参照されてないという言い方もおかしい
リテラルは単なる定数の簡略表記に過ぎず、ソースコード上だけの用語だ
実行時に消えてると言いたいのか?
そんなわけない、全く消えてない

138:デフォルトの名無しさん
24/09/14 00:51:01.21 8t7wdnSS0.net
>>132
CobolやFortranはこれからも生き残るよ
多分

139:デフォルトの名無しさん
24/09/14 08:27:14.72 QgTfRJpW0.net
>>134
言ってることが意味不明。
textセグメントとかbssとかdataセグメントとか知らんの?

140:はちみつ餃子
24/09/14 08:59:02.76 N2YvcTj50.net
>>134
> printfで中身が表示
意味が解らん。
表示されてる中身というのは foo の中身であってリテラルじゃないだろ。
> リテラルは単なる定数の簡略表記
整数リテラルなどは右辺値だが文字列リテラルに限っては左辺値。
文字列リテラルは実行フェイズにおいてオブジェクトとしての性質を持つということ。 (抽象機械の上では。)
ただし、この文字列リテラルが型変換された結果によって生まれるポインタはアドレス定数の要件を満たす。

141:デフォルトの名無しさん
24/09/14 10:32:56.64 0gsw2riP0.net
>>137
int i = 1;
printf("i -> %d\n", i);
この1は同じ様にリテラル表記以外に参照されてないというのか?

142:はちみつ餃子
24/09/14 10:49:21.06 N2YvcTj50.net
>>138
前述の通り整数リテラルは右辺値 (rvalue)。
文字列リテラルは例外的な存在だ。
まず、 C の用語では「オブジェクト」と「値」は違う意味を持つ。
メモリ上のビットパターンがオブジェクトで、値は式の結果だ。
(規格用語では data storage だがここではあえてカジュアルな用語で言うことにする。)
そして式の結果は lvalue と rvalue に区分される。
オブジェクトに結び付いている値が lvalue だと考えていい。
個々に規定があるので詳細は割愛するが、
式の中で変数名だとか単項 * 演算だとか [] とかがあればそれはメモリ上に存在してるのは明白だろ?
そういうのが lvalue 。
たとえば 1+3+5 みたいな式があれば途中で 4 という値が生じるが、これは「どこ」にある?
場所に結び付いておらず、式が終われば破棄されることになってる。
こういうのが rvalue 。
ちなみに lvalue も rvalue が要求される文脈では rvalue に変換される。 (メモリから値が読みだされる。)

143:はちみつ餃子 ◆8X2XSCHEME (ワッチョイ 7932-IU9Y)
24/09/14 12:58:36.93 N2YvcTj50.net
>>138
このときの 1 というリテラルは (rvalue の) 1 を返す式で、その値が i にコピーされた後で寿命を終えて消滅する。
printf の引数の i で取り出される 1 は i に入っている 1 であってリテラルの 1 じゃない。
整数リテラルはあくまでも整数を返す (生成すると言ってもいいかも?) 式であって、メモリ上のどこかにあるオブジェクトというわけじゃない。

144:デフォルトの名無しさん
24/09/14 13:32:49.89 0gsw2riP0.net
>>140
1は破棄されて"hoge"は破棄されないんだろ?
だから参照されてんじゃん

145:はちみつ餃子
24/09/14 13:40:20.14 N2YvcTj50.net
>>141
>>122 の bar が参照しているのは文字列リテラルからコピーされた配列であって文字列リテラルではない。
文字列リテラルが破棄されないこととは独立した話だよ。

146:デフォルトの名無しさん
24/09/14 13:43:47.04 0gsw2riP0.net
>>142
barは配列のコピーじゃないだろ
ポインターなんだから
コピーしてるのはアドレス値だぞ

147:はちみつ餃子
24/09/14 13:55:39.65 N2YvcTj50.net
>>143
そのポインタが指しているという意味で参照してると言ってる。
なにを言いたいんだ?
論点は「配列の初期化子として現れる文字列リテラルは配列の初期化以外に使われる可能性がない」という話だろ。

148:デフォルトの名無しさん
24/09/14 14:05:45.99 8t7wdnSS0.net
> char foo[] = "hoge";
> char* bar = &foo[1]; /* 敢えてずらしてみる */
> bar が参照しているのは文字列リテラルからコピーされた配列であって文字列リテラルではない。
説明がよく分からないが、barは、fooではなく、どこかにコピーした別の文字列なり配列を参照していると言うことか?

149:はちみつ餃子
24/09/14 14:20:52.41 N2YvcTj50.net
>>145
bar はどうでもいいよ。 それは要らん間接参照を入れて例としてよくわからんようになってるから
飛び飛びになってる私の書いてることをあらためてまとめると
・ char foo[] = "hoge"; といったような記述があれば "hoge" によって foo を初期化する。
・ このときの文字列リテラル "hoge" は foo を初期化するだけに使われて他からアクセスされる可能性がない。
・ 言語規格の建前上は文字列リテラルの寿命はプログラムの最初から最後までだが……
・ この場合は他からアクセスされる可能性がないから機械語レベルでは文字列リテラルは最適化で消えて (即値としてコードに埋め込んで) も問題にならない。

150:デフォルトの名無しさん
24/09/14 16:37:38.90 kHQOYHTcM.net
つまり
>>118 でgccが文字列を即値にする最適化の条件を推察したら
はちみつ餃子が規格の観点で説明が不適切ってぼこってるわけか?
前者の情報のほうが有益だわ

151:はちみつ餃子
24/09/14 16:47:20.53 N2YvcTj50.net
>>147
補足したつもりだが。
どう最適化するにしても規格に反する挙動にしてはならない (したら規格に対応しているとは名乗れない) からどうしてそれで規格に反しないのかの観点から説明した。

152:デフォルトの名無しさん
24/09/14 17:01:46.57 5H/bnNk90.net
最適化でどうなるかを考えながらC書くくらいならもうアセンブリ書いたほうが良いと思う

153:デフォルトの名無しさん
24/09/14 17:07:34.51 0gsw2riP0.net
>>146
はちみつは文字列リテラルがアセンブリソースの段�


154:Kで"hoge"と書かれてなければ消えてると思ってんだなw 例え命令コードの即値で書かれていても消えてる訳じゃないからー!残念! だから話が噛み合わなかったんだw まぁ強いて言えば、最適化でデータの表現法方を変えても構わないって言えば良い



155:デフォルトの名無しさん
24/09/14 17:14:48.19 0gsw2riP0.net
x = 1; ← 最適化で消えても構わない
x = 2;
最適化で消えても構わないってこういうことを言うんだよ
char foo[] = "hoge";
"hoge"は消えて良い訳ないだろw
gccは実際、命令コードに文字列を埋め込んでスタックに生成してるが、その文字列はポインター変数を使えば参照可能だ

156:はちみつ餃子
24/09/14 17:26:48.38 N2YvcTj50.net
>>149
それはそう。 原則としては言語の理屈に従っておくのが良い。
繰り返すけど、少なくとも初心者に対して低レイヤの観点で C を説明するのは筋が悪いと思う。

157:はちみつ餃子
24/09/14 17:33:13.32 N2YvcTj50.net
>>151
> 参照可能だ
その時参照してるのはスタック上にある配列であって、文字列リテラルではないってのを俺は何度書けばいいんだ?
文字列リテラルは本来は「プログラムの開始から終わりまでの寿命を持つオブジェクト」としてあらねばならないのが、
実際には文字列リテラルではない形になってることを「消えてる」と表現したのは確かに微妙な表現だったかもしれないが、
有るべき場所から消えてるんだからそんくらいわかるだろ。
そもそも最初は char* foo = "hoge"; との対比で言ってたんだから。

158:デフォルトの名無しさん
24/09/14 18:13:05.20 5H/bnNk90.net
はちみつ餃子の説明はたぶん、C++ の考え方が混ざっていないか
C で配列の初期化子に文字列リテラルが書けるのはあくまで文字列リテラル限定であって、それは式として扱われるのではなく、lvalue も rvalue もクソもないということだと思うが

159:はちみつ餃子
24/09/14 18:35:19.29 N2YvcTj50.net
>>154
初期化子の文法の一部であって式の規則の適用範囲外じゃないの?ってことだよね?
6.7.8 を見てこの場合でも式だと解釈してるけど、そういわれたらちょっと自信がないかも。

160:デフォルトの名無しさん
24/09/14 18:53:38.72 0gsw2riP0.net
>>153
その配列に格納されているデータが文字列リテラルから生成された文字列(の実体)だろ
厳密に言いたいなら、文字列リテラルはコンパイル時に存在さえしてれば良いものなんだよ
何しろ「リテラル」だから
それを生存期間だの実行時の実体とごっちゃにしてるから訳分かんないことになんだよ
コンパイル時にさえ存在してれば良いという事を実行時には消えてても良いとか言っちゃってんでしょ?

161:デフォルトの名無しさん
24/09/14 19:03:33.67 0gsw2riP0.net
char foo[] = { 'h', 'o', 'g', 'e', 0 };
文字列リテラルは↑のシンタックスシュガーだ
初期化子は消えても構わないのか?
初期化子が生成した文字列は参照出来ないと言うのか?

162:デフォルトの名無しさん
24/09/14 19:10:37.88 5H/bnNk90.net
>>155
URLリンク(en.cppreference.com)
ここ参考にしてたから文法定義の時点で式じゃないと思ってたけど、ちゃんと規格上は式としてのパースではあったね、すまない
改めて C99(でいいんだよね、6.7.8 ってことは)の draft 読んでみたけど、文字列リテラルで初期化できるのは 6.7.8.14,15 で特殊に定義された意味論であって、やっぱり式扱いじゃないんじゃないかね

163:はちみつ餃子
24/09/14 19:58:20.45 N2YvcTj50.net
>>154
結果的な挙動からするとどっちでも良いから書いてないだけかも。

164:デフォルトの名無しさん
24/09/14 20:16:47.07 8t7wdnSS0.net
皆拘らずに使っているのに言うのもあれなんだが
C言語にはC++で言う参照はありません

165:デフォルトの名無しさん
24/09/14 21:01:12.02 NQ2pFzob0.net
hogeは破棄されないって一人がんばってるID:0gsw2riP0を救済して差し上げたいが……自分も完全にわかってないのでできない。

166:デフォルトの名無しさん
24/09/14 21:04:22.62 tDLmxNl+0.net
実在するのはfoo[]だけで
文字列"hoge"は破壊どころか最初からあっても無くてもいいというのがここまでにわかったことだろ

167:デフォルトの名無しさん
24/09/14 22:15:49.35 zMI9sEnq0.net
配列と別に文字列もどこか別に確保しといて何の意味があるんだよ
この形で配列作る度に二倍メモリ食うことになるじゃないか

168:はちみつ餃子
24/09/14 22:32:05.03 N2YvcTj50.net
>>163
せやで。 だから最適化の余地があるという話をしてる。

169:デフォルトの名無しさん
24/09/14 22:34:31.27 8t7wdnSS0.net
ここで最適化の話は混ぜない方が良い

170:デフォルトの名無しさん
24/09/14 23:00:09.33 0gsw2riP0.net
>>163
clangは配列でも文字列リテラルは残ってるよ
ここって想像だけで語るアホばっかだなw
リテラルはコンパイル時のみに必要
それとは別に実行時にリテラルを実体化した値が存在する
基本的にrvalueだ
でないと当然初期化が出来ない
この値をはちみつは無視して語っている

171:デフォルトの名無しさん
24/09/14 23:04:40.23 0gsw2riP0.net
はちみつはリテラルはコンパイル時にのみ必要な事と、実行時には必要な初期値(rvalue)を最適化で命令コードに埋め込む事を消えたと表現して、ごっちゃにしてるアホ
これが結論

172:デフォルトの名無しさん
24/09/14 23:11:36.67 0gsw2riP0.net
リテラルは参照されないと言ってるのがその証拠
そりゃコンパイル時にのみに必要なその場でデータ構造を表現するリテラルを、実行時に参照出来る訳ないだろw
それが出来るのはコードをデータとして表現してるLisp だけだ
C++のテンプレートでも無理
C++のconstevalなら可能になった
std::formatはそれで実装可能になった
実行時には初期化の為のrvalueが絶対に存在する

173:デフォルトの名無しさん
24/09/14 23:13:53.14 0gsw2riP0.net
constevalも文字列リテラルを参照可能なのはコンパイル時のみだった…
やっぱり真に実行時に文字列リテラルを参照可能なのはLisp だけだな

174:デフォルトの名無しさん
24/09/14 23:40:13.14 5H/bnNk90.net
>>1 の C17 ドラフトのリンク C++17 のやつじゃん
次スレ立てるならこれに変えといて
URLリンク(web.archive.org)URLリンク(www.open-std.org)

175:はちみつ餃子
24/09/14 23:53:27.27 N2YvcTj50.net
>>167
起きていることは >>127 でこれ以上なく具体的に説明されてるんだから改めて厳密に表現しないと理解できないとは思わなかったんだよ。
>>168
文字列リテラルが静的記憶域期間を持つことは 6.4.5 に書かれてる。
実行フェイズに存在するオブジェクトだよ。 (最適化を抜きにして仕様通りに解釈すれば。)
配列の初期化子として現れる文字列リテラルの扱いは微妙かもという話が >>154 >>158 の指摘だが、
記憶域期間についての記述は文脈を指定せず文字列リテラル全部を対象にした記述に見える。

176:デフォルトの名無しさん
24/09/15 00:57:56.19 /wZr5+b/0.net
>>163
そりゃ書き換える場合があるからでしょー
一個しかなかったら関数呼ばれるたびに初期値も書き換わってしまう
なんで悩んでるのこの人?
constつけたら一個ですむだろ多分

177:デフォルトの名無しさん (ワッチョイ ffe1-1pYN)
24/09/15 01:17:55.27 STy65/7c0.net
>>171
> 実行フェイズに存在するオブジェクトだよ。
存在してんじゃねーかよ!
これが最適化で消えて良いかの話だよ!
gccの場合は命令コードに埋め込んでるけど、消えてる訳じゃないし、別のポインターから参照可能だ

178:はちみつ餃子 ◆8X2XSCHEME (ワッチョイ f732-vU+L)
24/09/15 01:30:47.17 B6k8li/O0.net
>>173
配列とその初期化子として現れる文字列リテラルが別の存在だってことが俺が何度も書いてることだよ。
これがそんなに何度も何度も何度も何度も書かないと理解できないようなことか?
別のポインタは配列を指せるが、その初期化子として現れる文字列リテラルを指せるわけじゃない。

char* foo = "hoge";

のようなケースではポインタ foo は文字列リテラルを指してるということと対比しての話だぞ。

179:デフォルトの名無しさん (ワッチョイ ffe1-1pYN)
24/09/15 01:32:35.13 STy65/7c0.net
ちなみに「文字列リテラル」が「実行時」に存在してる訳では全くない
はちみつはそこを勘違いしてる
静的記憶期間というのはスコープの事だ
まぁエクステントと言った方が正確だが
それはコンパイラーが理解できるものだが、それと「実行時」に存在する値を結びつけてはいけないし関係無い
DLLだとしたら静的記憶期間の変数も実行時には存在しない可能性もある
スレッドローカルストレージの変数もそうだな

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

180:デフォルトの名無しさん (ワッチョイ ffe1-1pYN)
24/09/15 01:38:12.52 STy65/7c0.net
>>174
> 文字列リテラルを指せるわけじゃない。
はい、これが間違いの全て
文字列リテラルはコンパイラーだけが理解できる「構文」に過ぎない
それを実行時にさせないとはこれいかに?w
文字列リテラルは「実行時」には何て名前になってんだ?
配列でもないぞ
配列に代入される前のrvalueの事だ
まぁ文字列は例外的にlvalueにもなれるが、rvalueであることには違いない

181:デフォルトの名無しさん (ワッチョイ 9f56-3vlU)
24/09/15 01:45:15.62 hg9QOZOF0.net
>>171
なんかいろいろ書いたけど最終的には自分もそれで合っていると思う
実用上は正直どこで役に立つのかあまり思いつかないが、規格上どういう建て付けになってるのかはとりあえず理解できたかも
というか、実用上あんまり役に立つわけじゃないから今まで調べもしなかったというか

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

うーんでもなあ
某言語でいきなり &1 とか書けるの知ってたら別に定数にも記憶域期間持たせればいいじゃんとか思っちゃうなあ
とりあえずそうなっているというだけか

182:はちみつ餃子 ◆8X2XSCHEME (ワッチョイ f732-vU+L)
24/09/15 01:46:17.50 B6k8li/O0.net
>>175
> 静的記憶期間というのはスコープの事

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

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

関数 (C のプログラムは関数の集合なので実質的にプログラムの全て) はオブジェクトではない。
私が「消える」と表現したのはこの意識があったからだが、機械語のレベルでどこかには存在するという意味ではそりゃ存在するだろう。
(同じ内容が連続する配列だったらループで書き込むような形にすることもあるかもしれない。)
配列の初期化子としての文字列リテラルは本来あるべき場所 (オブジェクト) から最適化で消えてるし、ポインタで指すことは出来ない。

183:はちみつ餃子 ◆8X2XSCHEME (ワッチョイ f732-vU+L)
24/09/15 01:53:34.48 B6k8li/O0.net
>>177
C++ の右辺値参照も左辺値参照も左辺値なんだよね。
参照を経由したら左辺値になるなら最初からそう出来ないか? と思ったことはある。

184:デフォルトの名無しさん (ワッチョイ ffe1-1pYN)
24/09/15 01:58:39.53 STy65/7c0.net
>>178
> ちがう。 記憶域期間はオブジェクトの寿命の区分。
だからエクステントと書いてんだろ!
もしかして理解出来なかったか?

> 配列の初期化子としての文字列リテラルは本来あるべき場所 (オブジェクト) から最適化で消えてるし
本来あるべき場所(オブジェクト)って何だよ?!
目茶苦茶だなw
これがコンパイラーと実行時に存在すべき値(rvalue)をごっちゃにした成れの果てだなw

185:デフォルトの名無しさん (ワッチョイ ffe1-1pYN)
24/09/15 02:33:43.11 STy65/7c0.net
初期化に使われた(文字列)リテラルが実行時にrvalueになったものに名前を付けるべきだな
これは最適化でも消えることはない(当たり前だが…)
名前がないとまたリテラルは消えるから参照出来ない野郎が発生しかねないw

186:デフォルトの名無しさん
24/09/15 12:24:08.15 WkBCL5VYd.net
>>174
>char* foo = "hoge";

>のようなケースではポインタ foo は文字列リテラルを指してる
その表現が間違ってる。
fooは静的記憶域を指してるが正しい。
intptr_t *bar = 0xAABB;
この場合数値リテラルを指すなんて言わんだろ。

187:
24/09/15 13:50:20.31 krajCak80.net
>>char* foo = "hoge";
>>
>>のようなケースではポインタ foo は文字列リテラルを指してる

>その表現が間違ってる。
>fooは静的記憶域を指してるが正しい。
彼も文字列リテラルは静的記憶域に置かれると言ってなかったっけ
僕にはこの2つの違いが分からないや
勘違いだったらごめんなさい

188:デフォルトの名無しさん
24/09/15 16:04:15.59 7leD3hDGM.net
もっと中身のある話しようぜ

189:デフォルトの名無しさん
24/09/15 17:53:23.56 V70NGKYC0.net
>>68
規格に後置++演算子は実数型とポインタ型にしか使えないとあったけどそれの関係じゃないの?
規格でそう決まってるだけの話では?

190:デフォルトの名無しさん
24/09/15 18:13:20.02 /tCGodXOd.net
それだな

191:デフォルトの名無しさん
24/09/15 21:42:32.09 /wZr5+b/0.net
ちなみに
int main(int argc, char *argv[])
と定義しても
argvは++できる

192:デフォルトの名無しさん
24/09/15 23:27:23.69 dUpBu3ui0.net
main の引数だけど、人によって好みがある
*argv[]だったり、 **argvだったり、
さすがにargv[][]はいないと思う

193:はちみつ餃子
24/09/16 08:22:23.81 JwEVxA0h0.net
>>185
配列はポインタに型変換される。 だから型は合うんだよ。
変更可能な左辺値でなければならないという制約に違反してる。

194:はちみつ餃子
24/09/16 08:28:07.90 JwEVxA0h0.net
>>182-183
静的記憶域期間ってのは静的+記憶域期間なんだよ。 静的記憶域+期間じゃないんだよ。
まあ静的記憶域期間を持つオブジェクトが配置されている場所を静的記憶域と呼んでもカジュアルな場面ではそんなに不自然ではないとは思うけど。
実装上は専用のセクションに配置するのが普通だし。

195:デフォルトの名無しさん
24/09/16 08:30:39.50 +a4Swf1f0.net
ここまでのまとめ
Cは生産性が低い
C使いも生産性が低い

196:デフォルトの名無しさん
24/09/16 10:51:57.39 yKwOC4kA0.net
ID:+a4Swf1f0 は、言語に何使おうと生産性が低そう

197:デフォルトの名無しさん
24/09/16 11:29:42.22 0nzerU0W0.net
>>191,192
生産性など、君ら社畜を計る尺度に過ぎんよ。
芸術家は、時間をかけて1行の美しさを追及するものだ。

198:デフォルトの名無しさん
24/09/16 12:43:08.20 T6H9+ne50.net
>>189
変更可能な左辺値に配列型は含まれないからそれとは違うん?いつポインタに型変換されてんの?

199:はちみつ餃子
24/09/16 13:26:14.08 JwEVxA0h0.net
>>194
6.3.2.1 より
> 左辺値がsizeof演算子のオペランド,単項&演算子のオペランド,又は文字配列を初期化するのに使われる文字列リテラルである場合を除いて,
> 型“〜型の配列”をもつ式は,型“〜型へのポインタ”の式に型変換する。
式として出てくる配列は一部の例外を除けば問答無用で変換されるので ++ のオペランドに配列が出てくるときも変換後のポインタ (rvalue) に対する演算 (実際には出来ないけど) として解釈されるということでいいと思う。

200:デフォルトの名無しさん
24/09/16 14:56:21.22 T6H9+ne50.net
>>195
配列オブジェクトの先頭の要素で左辺値じゃないって書いてあるな
ということは左辺値の式の中に出てくる配列は左辺値じゃなくなっちゃうということ?
なんでそんな仕様になったんだろうね

201:はちみつ餃子
24/09/16 16:28:24.01 JwEVxA0h0.net
>>196
C には配列の要素を指すポインタとは別に配列を指すポインタというものもある。
こんなことが出来る。
int foo[10];
int (*bar)[10] = &foo;
このときの bar の型は int(*)[10] ということになるわけだが……。
型情報として長さが含まれるのはかえって邪魔だ。
大抵の配列を受け取る関数 (str系やmem系など) は配列の大きさが固定ではないから。
配列の先頭要素で配列を代表させる (それが簡単な記法にする) ほうが都合がよかったんじゃないかと思う。
配列全体をひとつの値として扱いたい場合のほうが少ないだろうという判断もそれなりに合理的じゃないかな。
いまどきの言語 (Go とか Rust とか) は範囲を表すスライスという概念を導入して解決してるけど、
C の登場時期だと 2 ワードのオブジェクトを基本型にするのってなんかヤじゃない? と思ったとしても仕方ない。

202:デフォルトの名無しさん
24/09/16 17:22:11.94 udznqyd1d.net
>>190
横からすまんが、記憶域期間って言葉も変

203:デフォルトの名無しさん
24/09/16 17:23:46.99 udznqyd1d.net
>>189
>配列はポインタに型変換される。
それは関数呼び出しの場合だぞ

204:デフォルトの名無しさん
24/09/16 17:29:54.17 E0fXFEgV0.net
この糞コテは半端知識のかまちょだからNGやスルー推奨

205:はちみつ餃子
24/09/16 18:10:03.54 JwEVxA0h0.net
>>199
こっちは根拠になる規格の文面を提示してるんだから違うというなら違うと思う根拠を提示して。

206:デフォルトの名無しさん
24/09/16 18:57:26.00 ISRAyNkZa.net
>>188
そらargv[][]では誤りだもんな

207:デフォルトの名無しさん
24/09/16 21:32:46.16 NNTpe0yPa.net
>>187
たしかに関数の引数だと違うんだな
URLリンク(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 は出来ない
URLリンク(ideone.com)

208:デフォルトの名無しさん
24/09/16 22:10:35.73 hHcIxSUD0.net
>>197
流石に言ってる事が的外れ過ぎるのでもうちょっと勉強した方がいいと思うよ

209:
24/09/16 22:25:26.45 z+htC2pc0.net
恥ずかしながら、静的記憶域期間(で合ってるのか?)という言葉を知らなくて、ライフタイムは「静的」に含意されているのかと思ったワ…
しかし、記憶域期間って違和感あるなぁ

210:
24/09/16 22:30:23.39 z+htC2pc0.net
わけわからん
>>205は撤回します

211:はちみつ餃子
24/09/16 22:43:01.97 JwEVxA0h0.net
>>203
余談だけど配列だけじゃなくて関数型も関数ポインタ型に調整されるよ。

212:デフォルトの名無しさん
24/09/16 22:52:59.17 TDYyKtgo0.net
>>201
規格に配列は常にポインタに変換されるなんて書いて無いぞ。

213:デフォルトの名無しさん
24/09/16 23:00:53.05 f3T7KT8T0.net
>>208
「常に」とは書かれていない
「ポインタに変換される」ではなく「ポインタに型変換される」
>>102がまさにそれでしょ
E1という配列が関数呼び出しでない場合においてもポインタという型に変換されているから出来ること

214:デフォルトの名無しさん
24/09/16 23:10:52.64 yKwOC4kA0.net
>char *hoge(char fuga[10])
こう書いてあっても、関数内で10を使う訳ではない
関数内で仮に100個めの要素アクセスするロジック書いてもエラーにはならない
(実行時にはエラーになると思う、多分)
だから、
>char *hoge(char fuga[])
添え字無しにしても良いことになる

215:デフォルトの名無しさん
24/09/17 01:04:31.11 BokinMog0.net
>>210
元々ローカルでchar hage[10];と定義して10以上をアクセスしてもコンパイル時にはエラーにならないでしょ
引数に[10]と書くとしたら可読性のため(この関数では[0~9]までアクセスする可能性があると明示するため)

216:デフォルトの名無しさん
24/09/17 10:15:58.36 9gub94Dsd.net
__FILE__ とか __LINE__ は大文字なのになんで __func__ は小文字なん?

217:デフォルトの名無しさん
24/09/17 10:17:16.72 TMGdiCOOa.net
範囲の問題じゃなくて
++hage または hage++ が出来るか出来ないかが問題なんです

218:デフォルトの名無しさん
24/09/17 11:06:41.56 bX/ekV+z0.net
一見配列を受け渡ししているように見えるけれど、
実際はポインターとして受け渡ししているってことでしょ

219:はちみつ餃子
24/09/17 11:56:03.91 FRc2ySeD0.net
>>212
__func__ はマクロではないからだと思う。

220:デフォルトの名無しさん
24/09/17 12:47:41.54 bX/ekV+z0.net
#include <stdio.h>
char hage[10] = {0};
char *hoge(void)
{
// ++hage; // error '++' には左辺値が必要です。
// return hage;
 return &hage[1];
}
int main(void) {
 char *p = hoge();
 printf("%p, %p\n", hage, p);
 return 0;
}

221:デフォルトの名無しさん
24/09/17 13:07:46.14 TMGdiCOOa.net
>>214
そんなことは判ってるよ
(char hage[10]) で hage++ または ++hage 出来ちゃってる(ように観える)のが問題なんでしょ
関数の引数は (char hage[]) または (char *hage) のみにすれば良かった
(char hage[10]) はどうみても蛇足(結局境界テストされてないし)

222:デフォルトの名無しさん
24/09/17 13:11:47.81 bX/ekV+z0.net
問題だと思う人は、使わないようにしましょう
開発サイトでそういうルールを用意するのも手です

223:デフォルトの名無しさん
24/09/17 17:17:11.73 9gub94Dsd.net
>>215
納得しました。

224:デフォルトの名無しさん
24/09/17 20:17:27.08 dLWvmxgr0.net
>>197
そもそもstr系mem系はアドレスを受け取るんであって配列を受け取る関数ではないっていう勘違いがあるんだけど
それはともかく大きさがどうのとかなんちゃらが都合がいいとか、本当にC言語でなんかプログラムを書いた事あるの?

225:デフォルトの名無しさん
24/09/17 20:58:19.23 9gub94Dsd.net
俺は尻より胸派なんだよね。

226:デフォルトの名無しさん
24/09/18 00:42:28.78 wcwImUMc0.net
>>217
この場合に限らずcでは範囲チェックなどされないでしょ
必要なら自分でチェックするのが原則
void aaa(char hage[10],int idx)
{
if((UINT)idx < sizeof(hage)/sizeof(hage[0]))
printf("%d=%d¥n",idx,hage[idx]);
else
printf("%dは範囲外だhage¥n",idx);
}
これなら[10]に意味が出る

227:デフォルトの名無しさん
24/09/18 01:22:58.84 9DvoA/Ly0.net
ド素人w

228:デフォルトの名無しさん
24/09/18 05:59:54.60 Y3+kk9yU0.net
>>222
c faq 6.21 (英文が詳しい)
URLリンク(c-faq.com)
>>207 の'調整'は'adjust'だろう
N1256を'adjust'で検索するのじゃ
Look, a new day has begun.

229:デフォルトの名無しさん
24/09/18 07:51:55.61 9Z5pFVfx0.net
8/16bit時代の1バイトでも、1ステップでも減らせってのを経験した人と
最近の可読性、移植性、安全性優先設計が当たり前世代とのギャップ。

230:デフォルトの名無しさん
24/09/18 08:59:57.51 9DvoA/Ly0.net
ギャップの問題じゃねーから
文脈すら理解できないじじいはすっこんでろ

231:デフォルトの名無しさん
24/09/18 09:30:25.30 Qk7JHPx80.net
専門板によくいるアスペだな

232:デフォルトの名無しさん
24/09/18 10:34:45.37 UYQxUcxO0.net
225 は釣りでしょう

233: 警備員[Lv.2][新芽] (ワッチョイ bfd9-/vo+)
24/09/18 13:08:51.24 eTGNACyx0.net
>>222
sizeof(hage) で配列のサイズが求まるの?
と思ったら、「char * (ポインタ)の大きさを返すよ」みたいな警告が @gcc

234:デフォルトの名無しさん
24/09/18 13:15:29.42 UYQxUcxO0.net
釣りだか天然だか、分からなくなってきた 笑

235:はちみつ餃子
24/09/18 13:35:28.77 td/rS/wM0.net
今どきの統合開発環境を使ってるなら変数の型くらい見れると思うけれど
古典的な手法としてあえてエラーにしてメッセージを読むという型の確認方法がある。
void foo(char bar[10]) {}
int main(void) { int baz = foo; }
こんなコードをたとえば gcc でコンパイルを試みると
error: initialization of 'int' from 'void (*)(char *)' makes integer from pointer without a cast
というエラーになる。
foo の型が void (*)(char *) であることがわかる。
foo は関数型の式 (関数指示子) なので暗黙に関数ポインタに型変換されているのと
bar に相当する箇所の型が char* になってるのがわかる。

236:
24/09/18 13:51:08.91 eTGNACyx0.net
なるほど
勉強になります

237:デフォルトの名無しさん
24/09/18 14:54:11.13 LEoKOQZWd.net
>>222
>この場合に限らずcでは範囲チェックなどされないでしょ
>必要なら自分でチェックするのが原則

>void aaa(char hage[10],int idx)
>{
> if((UINT)idx < sizeof(hage)/sizeof(hage[0]))
> printf("%d=%d¥n",idx,hage[idx]);
> else
> printf("%dは範囲外だhage¥n",idx);
>}

>これなら[10]に意味が出る
printf("%uz\n", sizeof(hage)/sizeof(hage[0]));
の結果ってどんな値表示されるの?

238:デフォルトの名無しさん
24/09/18 14:56:10.00 LEoKOQZWd.net
書式のとのuzじゃなくてzuだっけ?zだけでよかったっけ?
ま、主旨はそこじゃないからいっか。

239:はちみつ餃子
24/09/18 15:47:33.09 3rwci13t0.net
>>233
sizeof(char*)/sizeof(char) ということになる。
sizeof(char) は確実に 1 だから結果としては単に char* のバイト数ってことだね。
この場合は「『もし 10 に意味があるとしても』境界チェックはされないことに変わりないのでなんの役にも立ってない。 役に立てるとしたらここまで書かなきゃならない」というのが主旨なのであくまでもしもの話。
実際の値はどうでもよい文脈だと思う。

240:デフォルトの名無しさん
24/09/18 16:33:08.44 wcwImUMc0.net
>>224
ああそうなの
昔のことだから記憶違いをしてたようだ

241:デフォルトの名無しさん
24/09/18 16:43:30.74 LEoKOQZWd.net
>>235
>>222 の「これなら[10]に意味が出る」ってのは間違いってことね。

242:デフォルトの名無しさん
24/09/18 18:00:34.97 wcwImUMc0.net
'ここの10は意味ありませんよ'
って警告を出してもいいじゃんってことでしょ
それなら例えば
typedef char HAGE_TBL[10];
void foo(HAGE_TBL hage) {}
(毎回10とか書くのは危険なのでこういう使い方が多いと思う)
などとした場合に毎回警告が出てうざいことになるんじゃないか

243:デフォルトの名無しさん
24/09/18 18:07:31.49 UYQxUcxO0.net
警告ならまだ笑っていられるが、
明らかに書いた奴の意図とは違って誤動作してるだろ

244:デフォルトの名無しさん
24/09/18 18:30:29.69 LEoKOQZWd.net
>>222 のバグを晒すスレはここですか?

245:デフォルトの名無しさん
24/09/18 18:46:04.44 LEoKOQZWd.net
C言語は難しいな

246:デフォルトの名無しさん
24/09/18 20:53:02.12 UYQxUcxO0.net
void aaa()の中で、
引数で渡された値が何かを確かめて見ると良い
それと、 sizeof(hage)やsizeof(hage[0])の値も
プログラム書いた人の意図としては、
sizeof(hage)/sizeof(hage[0])が10になるはずなんだが
さてさていくつだろうか?

247:デフォルトの名無しさん
24/09/19 00:15:21.84 5H+5PGV10.net
もうやめて!>>222 のライフはゼロよ!

248:デフォルトの名無しさん (ワッチョイ 9f1e-S785)
24/09/19 06:32:15.59 zdFAvN1E0.net
本人が新たなネタを出してくるんだもん。


249:href="/test/read.cgi/tech/1721137434/238" target="_blank">>>238 でもわざわざ typedef char HAGE_TBL[10]; ってやっておきながら、なんで void foo(HAGE_TBL hage) なの? 構造体と同じように void foo(HAGE_TBL *hage) ってしてみたら新たな何かが見えてこないかい?



250:デフォルトの名無しさん
24/09/19 15:36:15.62 bQAYIDF0M.net
cは洗練された型システム持ってないんだからそんなところ頑張っても無駄なんだよ
この悟りに至って始めて脱初級
原則語るならそれからにしてくれ

251:デフォルトの名無しさん
24/09/19 15:40:30.12 cPR7xA8Z0.net
Cは一部の洗練された型システム持つ言語よりも遙かに自由度が高い
そこが分かってようやく中級レベル
あとは本人の努力次第で空も飛べるし海も潜れる

252:デフォルトの名無しさん
24/09/19 15:50:31.78 c2v//UgT0.net
おいおい
そのぶん危険なんだから持ち上げる部分でもないだろ
お前も初級

253:デフォルトの名無しさん
24/09/19 17:19:57.71 cPR7xA8Z0.net
ナイフは危険だが有用
不器用者は使わない方が良い

254:デフォルトの名無しさん
24/09/19 17:44:18.26 8NYyNXbk0.net
>>244
typedefは新たな型を作るわけじゃない別名を定義するだけから
void foo(char hage[10])

void foo(HAGE_TBL hage)
は同じことだよ

255:デフォルトの名無しさん
24/09/19 20:28:27.65 c2v//UgT0.net
>>248
c言語ってとっくの昔から自由にキャストしまくれる言語じゃないの知ってるか?
さぁお前はなんと答える?

256:デフォルトの名無しさん
24/09/19 20:47:13.84 cPR7xA8Z0.net
そんなに怖がるなよ
食われるわけじゃないんだから

257:デフォルトの名無しさん
24/09/19 21:11:19.13 /CBFTgYsa.net
>>245
悟った人は全部void*

258:デフォルトの名無しさん
24/09/19 21:52:43.48 j90utfqH0.net
文字も数字も全部intでいいやん

259:デフォルトの名無しさん
24/09/19 21:56:05.41 /CBFTgYsa.net
getch() は int

260:デフォルトの名無しさん
24/09/20 07:15:20.20 dn4N5ANS0.net
>>249
それが不満なようだから「HAGE_TBL * にしたら何ができるか考えてみては?」ということでは?

261:デフォルトの名無しさん
24/09/24 10:26:30.49 /2yiAcKTp.net
昔のコンピュータはメモリー少ないから、intで文字持つなんて贅沢だったんだよ

262:デフォルトの名無しさん
24/09/24 11:12:54.47 CARZyoOh0.net
次のジジイの的外れな言いたいだけコメントを先取り
intは16bit以上だぞ

263:デフォルトの名無しさん
24/09/24 11:31:50.53 QMMOdtbOp.net
違うよ、intは処理系依存だから8ビットの場合もある

264:デフォルトの名無しさん
24/09/24 11:49:08.20 vvKB2ofDd.net
規格書読め

265:デフォルトの名無しさん
24/09/24 11:54:52.88 kMxfGMRcM.net
次のジジイ
getcharがなぜintを返すか

266:デフォルトの名無しさん (ワッチョイ d6f5-K4S3)
24/09/24 19:39:49.05 tv/lKhnI0.net
>>174
> char* foo = "hoge";
>
> のようなケースではポインタ foo は文字列リテラルを指してる

(単に端折っただけかもしれないけれど、)文字列リテラルに関してCには非常に込み入った事情(Rationale Rev. 5.10 6.4.5 冒頭-l.26, N1256 Annex J.5.5)があり、厳密に言えば foo は "hoge" によって初期化された無名の配列を指している(N1256 6.7.8-32)。

C99RationaleV5.10
URLリンク(www.open-std.org)
テンプレ入りキボンヌ

>>皆の衆
ともあれ、込み入った事情に該当しなければ
const char afoo[] = "hoge";
あるいは
const char * const ccfoo = "hoge";
場合によって
const char *cfoo = "hoge";
と書いて、うっかり書き換え防止に勇往邁進するのじゃ。

267:261 (ワッチョイ d6f5-K4S3)
24/09/24 19:51:57.01 tv/lKhnI0.net
>>158
件の意味論は 6.7.8-32 を介して 6.7.8-14,15 に帰結するように思われる一方で、文字列リテラルが 6.4.5-5 で自ら初期化した(やはり)無名の配列の代名詞だとすると 6.7.8-11 が適用されるという解釈も成り立ちそう。

char *gfoo1 = "hoge"; // (1)
char *gfoo2 = "hoge"; // (2)

void f() {
char *foo1 = "hoge"; // (3)
char *foo2 = "hoge"; // (4)
}

>>261 で触れた文字列リテラル書き換え派の場合、(1)~(4)は別物なので、各々初期化しなければならないため前者の解釈。この時、(3), (4)が automatic storage duration でも良いように 6.7.8-32 では storage duration を定めていないのだと思う。
他方、文字列リテラル不変派の場合、(1)~(4)は同一で良いので、初期化を一回で済ませて後者の解釈。
結局、前後者両方の解釈が出来るようになっているように見える。

268:デフォルトの名無しさん (ワッチョイ de79-sesJ)
24/09/25 19:34:19.49 8eNfi/Op0.net
まだやってるキモ…
いくら話題無いからってこれは誰も幸せにならない

269:デフォルトの名無しさん
24/09/25 23:05:12.18 YARyzAjz0.net
ええんちゃう別に
どうせ5chに答えを求めてやって来る人なんてもうおらんのやし

270:デフォルトの名無しさん
24/09/25 23:07:41.16 1jKu7Jqx0.net
青い鳥を探してます
ここに来れば教えてくれると聞いて来ました

271:デフォルトの名無しさん
24/09/26 09:49:09.10 oesVQEFi0.net
PythonとかC++のスレで規格持ち出して言い合いしてるのを見たことないが
何故かここではよく起こるな

272:デフォルトの名無しさん
24/09/26 10:19:33.26 944iXMZC0.net
Cなんてのは対象CPUの違いとかでも標準とかけ離れた実装して来るのにね

273:デフォルトの名無しさん
24/09/26 10:58:03.72 R5lWYvWFa.net
>>264
これ++

274:はちみつ餃子
24/09/26 12:24:13.03 B+Au+yIB0.net
>>266
じゃあ何を根拠にしてるの?
妄想?

275:デフォルトの名無しさん
24/09/26 14:46:28.31 oxN8/Up7M.net
perlあたりで頼む

276:デフォルトの名無しさん
24/09/26 16:39:09.57 oesVQEFi0.net
>>269



277:Nの問題点は規格読んでるの間違えてるとこだよ



278:はちみつ餃子
24/09/26 16:48:57.66 B+Au+yIB0.net
>>271
規格を根拠にしてたら間違えてる箇所は間違えていると反論できるだろ。
根拠がないよりは良い。
ところでどこに間違いがあった?

279:デフォルトの名無しさん
24/09/26 23:55:11.03 jCy2QsTx0.net
>>235
これの1行目は文字列長によらず固定値にならない?
char* と char[] を区別できてないように思う
// これは (ヌル文字を含む) 4バイトのデータがスタック上に作られる
// sizeof(a1) の結果は文字列数により変わる
char a1[] = "abc";
// こう書いた場合、文字列の実体は静的な領域 (テキスト領域) に確保され、
// a2にはそのアドレスが渡される。
// sizeof(a2) はポインタのサイズであり、値は文字列長によらず固定
char* a2 = "abc";

280:デフォルトの名無しさん
24/09/27 00:02:43.63 ju4/Ooeg0.net
char* でも char[] でも、a[n] と書けばn文字目を参照するのは変わらない
これはポインタの [] 演算子は「ポインタをn個進めた位置の要素を参照する」ため、結果的には配列と変わらないから
だけど前述の a1 と a2 は違う型なので、そこは注意が必要
たぶん VS Code でC言語の拡張を入れてれば、上記のように書いた変数のところにカーソルを当たるとヒントが出るので、それで確認できると思う
それか実際に動かして sizeof の結果を見るか

281:はちみつ餃子
24/09/27 00:16:01.96 dEIfxD4z0.net
>>273
> これの1行目は文字列長によらず固定値にならない?
その通りだよ。 固定値になってたぶん意図通りではない。
その話は >>222 がボコボコに言われてもう終わったよ。

282:デフォルトの名無しさん
24/09/27 00:20:08.16 qUi2cfOF0.net
もう >>222 を晒すのはやめてあげて......

283:デフォルトの名無しさん
24/09/27 00:22:55.64 xb00usC10.net
222は釣りでしょう

284:はちみつ餃子
24/09/27 00:23:40.17 dEIfxD4z0.net
あ、ひょっとすると >>273 は話題を誤解してるのか。
「仮引数が配列形式だった場合にポインタに調整されるルール」が話題の中心。
仮引数として現れないと意味ない。

285:デフォルトの名無しさん
24/09/27 07:31:58.10 ju4/Ooeg0.net
>>278
すまん自分が直近のレスだけ見て話題を早とちりしてた
だいたい流れは分かった

286:デフォルトの名無しさん
24/10/15 13:20:49.22 +DYHSMWW0.net
初歩的な質問で申し訳ないんだけど
プログラムをユーザーの入力によって一時停止させるのってどうしたら良い?
pauseで入力待ちにするとかフラグを間に挿入するとかではなくユーザーからの入力があった場合のみ一時停止したい

287:デフォルトの名無しさん
24/10/15 13:29:34.78 WZg8MP0BM.net
まずメインの処理を一時停止可能な作りに変える

288:デフォルトの名無しさん
24/10/15 13:32:02.14 nD7e5Gmv0.net
>>280
ソースコードの中にファイル名がpauseのファイルが存在するかを判断するロジックを追加
もし存在するならループに入りそれが消えるまで待てばいい

289:デフォルトの名無しさん
24/10/15 13:32:39.39 WZg8MP0BM.net
あとコンソールプログラムなのか?
環境を正確に書きな

290:はちみつ餃子
24/10/15 13:37:01.44 C4BE9tl00.net
>>280
C は言語として規定している範囲はかなり狭くて、細々とした制御には環境依存の方法が必要になることが多い。
ホスト環境によって作法が違う。

291:デフォルトの名無しさん
24/10/15 13:47:40.16 +DYHSMWW0.net
>>281
根本からなのね
>>282
初心者なもんで、一つのファイル内で完結したら嬉しいなーなんて
>>283
とりあえずコンソールで作ってる
環境はVS2022だけでおk?
>>284



292:ソょっと前古いサイト参照してたら環境違いすぎて苦労したし古い言語の宿命なんすかね



293:デフォルトの名無しさん
24/10/15 13:51:52.41 9xoHIO4Lp.net
環境依存でデバイス依存だからなぁ

294:デフォルトの名無しさん
24/10/15 14:34:22.10 UH8LrgydM.net
やりたいことがnon blockingでgetcharしたいってことだとするとwindowsだconsole apiを使う
例えばwindowsのreadline互換実装であるwineditlineを見るといい

295:デフォルトの名無しさん
24/10/15 14:36:11.97 UH8LrgydM.net
ただめんどうなので今回のように止めたいだけならこういう簡易的なやりかたがある
URLリンク(stackoverflow.com)

296:デフォルトの名無しさん (ワッチョイ 2b65-ebyo)
24/10/15 20:06:43.67 +DYHSMWW0.net
>>287
一行目の通りで合ってると思う
念の為やりたいことを挙げておくと、メディア再生中の一時停止とかゲーム中のポーズ画面みたいなものだと思ってもらえれば良い
ただ、2行目のreadlineは日本語でググったりヘルプで検索かけたけどよくわからん
>>288
すごい簡単だね、これなら作れるかもしれない
入門書に記載がないのが唯一の不満だよ

297:はちみつ餃子
24/10/15 21:39:15.79 C4BE9tl00.net
>>285
言語の古さというより用途だろう。
低レイヤ部分を実装する用途に使う言語だから重厚なランタイムサポートを必要とする機能は入れられない。

298:デフォルトの名無しさん
24/10/30 01:54:25.92 BzmMNap80.net
いにしえの議論掘り返してすまんが、>>182の例示による説明が最も本質を突いてるように思う、感謝のレス

文字列リテラルは配列初期化子の構文糖でありながら、また文字列をも表すという二義性を持つ、という云うのはあくまで言語設計の為の汚いハックでしかなかろ?

299:デフォルトの名無しさん
24/10/30 10:28:23.97 BRGgIRAsp.net
Cの変数の型指定なんて気休めだからなぁ

300:デフォルトの名無しさん
24/11/01 06:24:42.85 +lXxXu7p0.net
気休めじゃなくて気疲れの間違いだろ
長さやsignednessでわけわからん変換しやがるバグの根源と言ってもいい

301:デフォルトの名無しさん
24/11/01 11:11:58.05 YgeQjLzz0.net
訳が理解できるようになるまで、お前は使用禁止

302:デフォルトの名無しさん
24/11/03 13:27:09.33 N1lOck0q0.net
URLリンク(togetter.com)
こんな事本当にあるのか?

303:デフォルトの名無しさん
24/11/03 13:36:34.35 e8fWHn4Q0.net
もともとバグってたのを対処療法で回避しただけじゃねーの?
そんな驚愕するほどのこととは思わんな
スペースは文字列に加えるってことだろ

304:デフォルトの名無しさん
24/11/03 13:45:35.99 WzNRcFfL0.net
ちゃんとソースを公開すればみんなで治してくれるよ

305:デフォルトの名無しさん
24/11/03 16:06:15.80 XxnHrPnRa.net
バイバイおさるさん

306:デフォルトの名無しさん
24/11/03 17:27:36.06 4RaSizfZ0.net
char []s = "うんこ"
s[20] = 0; // どっか判り難いとこにこんなのが紛れてる
回答「(sに)もっとスペースを追加して!」

307:デフォルトの名無しさん
24/11/03 17:39:48.03 WzNRcFfL0.net
どこか知らない国で "うんこ" が40バイトくらいある所があったりして

308:はちみつ餃子
24/11/03 19:33:15.95 /vDzNoeA0.net
業務だとヨソの担当のモジュールに口出しするのがめんどいから対処療法で握りつぶすみたいなことはあるのかもしれん。

309:
24/11/03 20:22:14.37 5dhdDFeF0.net
s("※んこ"の値)は�


310:ヌみ取り専用になるんじゃないかな 処理系によるかもしれないけど



311:デフォルトの名無しさん
24/11/04 01:39:12.77 rgFUj3k30.net
>「ここにスペースを入れてみて」「もっと沢山、もっともっと」
この辺りコピペ怪文書にしか思えないんだが
境界チェックしない言語ならありふれたバグだし、元文書はちんぽとかだったんじゃないだろうか

312:デフォルトの名無しさん
24/11/04 13:45:59.93 UGhFqLBmp.net
どうせメモリーリークだろうな
データ位置を変えると現象が変わるなんて典型的だろ

313:
24/11/04 13:48:37.25 nJwTTfVk0.net
>>302
誤りでした

314:デフォルトの名無しさん
24/11/04 14:02:09.24 SHEOgeyw0.net
パンパース当てるのが正しい

315:デフォルトの名無しさん
24/11/04 20:44:45.70 rgFUj3k30.net
おむつってあんま進化してないよな
吸収率だとか漏れだとかそんなのは上がってるだろうが、基本的な機能は変わらない
介護業界でも排泄介助っていう高齢者の汚物処理って割と大変な部類だと思うんだが
そろそろおもつ革命を起こさないと業界崩壊するんじゃないの
プログラミングでなんとかできませんかね

316:デフォルトの名無しさん
24/11/04 20:51:48.25 rgFUj3k30.net
高齢者に限らず若い子でもうんこ漏らす時は漏らすし、そういう緊急時にも安心できるぐらいのものがそろそろ欲しいな
紙ベースで吸収率だとかで脳が退化してるおむつメーカーではおむつ革命はとても期待できないだろう

317:デフォルトの名無しさん
24/11/04 21:52:48.49 lap6rdZH0.net
介護対象に飲ませるうんこがあまり臭くなくなる薬みたいな技術は進化してるぞ

318:デフォルトの名無しさん
24/11/04 22:10:34.76 TtMQ1IOc0.net
薬で臭くなくしたうんこだからといって介護対象に飲ませるのはどうかと思うぞ。

319:デフォルトの名無しさん
24/11/04 22:15:25.35 lap6rdZH0.net
>>295
こんなんじゃね

#include <stdio.h>
#include <string.h>
#include <limits.h>

int main(void)
{
  char s[] = ""; // ←スペースを11個入れる
  sprintf(s, "%d", INT_MIN);
  puts(s);
}

320:デフォルトの名無しさん
24/11/04 22:17:04.25 lap6rdZH0.net
>>310
完全に臭くなくなる訳ではないのでおk

321:デフォルトの名無しさん
24/11/04 22:57:47.13 nqjJRhEX0.net
ニホンゴ ムズカシイネ

322:デフォルトの名無しさん (ワッチョイ 92ad-guIA)
24/11/05 05:14:52.21 srt1vo+S0.net
逆に考えるんだ。うんこはどうしても出てしまう。だったらそれはそのままにしておけ。
介護する側がそれを気にせず処理出来るのであれば問題は消滅する。だから介護者が
それを気にならなくなるような精神に効く薬を作れば良いんだ。

323:デフォルトの名無しさん
24/11/05 06:59:24.91 tCS75Iej0.net
>>295って実行時エラーの話なのかコンパイル時エラーの話なのかもわからなくない?

324:デフォルトの名無しさん (ワッチョイ b5b4-8Jbz)
24/11/05 15:17:41.47 wPeW8RQX0.net
NASAはネットなんてなかった1970年代にボイジャー1号打ち上げて
240億km離れててもプログラムを送受信してるのに俺らときたら

325:デフォルトの名無しさん
24/11/05 21:46:02.31 JaQWNq5Na.net
どうみても脳筋エラー

326:デフォルトの名無しさん
24/11/05 21:49:31.93 qHb8dozk0.net
脳筋がCを使いません

327:デフォルトの名無しさん
24/11/05 22:03:42.83 MR2KM4Hj0.net
240億kmの伝書鳩

328:デフォルトの名無しさん (ワッチョイ 3679-NO1F)
24/11/06 09:37:06.45 csbv8Qbd0.net
1970年代にもテレビやラヂオはあったわけでね…

329:デフォルトの名無しさん
24/11/07 17:53:15.92 RjbHlnZn0.net
1960年代はラジオ少年が秋葉原詣でしてたな

330:デフォルトの名無しさん
24/11/07 22:04:17.92 E5qLHtEE0.net
質問失


331:礼 LPTSTR lptStr = TEXT("テスト"); って書くとE0144とC2044ってエラーを吐くんだがプロパティの文字セットって項目を設定なしにすると正常に処理されるのはどういう理屈なの? const wchar_t[]からLPTSTRに変換できませんってメッセージ出るし型が違うのかなと思うが だとしたら何故文字設定いじれば解消するのかもよくわからない



332:
24/11/07 22:09:23.47 QiubzAbP0.net
LPCTSTR ではダメですか?
当てずっぽうですが

333:
24/11/07 22:10:11.25 QiubzAbP0.net
>>323
そういうことじゃないのか、ごめんなさい

334:デフォルトの名無しさん (ワッチョイ f637-UxC2)
24/11/08 09:56:22.05 tVfxyvn80.net
>>322
設定変えても依然エラーだが
VS Community 2022

335:デフォルトの名無しさん (ワッチョイ 7161-m4Ma)
24/11/08 10:31:35.11 +8UCAN2P0.net
>>324
気持ちだけで十分よ

336:デフォルトの名無しさん (ワッチョイ 7161-m4Ma)
24/11/08 10:32:35.47 +8UCAN2P0.net
>>325
2022だと設定項目見つからなかったから2012でやった、そしたら上記の結果になるんすよねえ

337:デフォルトの名無しさん (ササクッテロラ Sp79-P7MY)
24/11/08 10:36:22.46 ce4XJJ6Np.net
最近のVSはCの当たり前な構文が通用しないから困るよな

338:デフォルトの名無しさん (ワッチョイ 7161-m4Ma)
24/11/08 10:51:18.29 +8UCAN2P0.net
>>328
Visual Studio側の問題なのこれ?

339:デフォルトの名無しさん
24/11/08 11:51:09.67 y6pbbxPDM.net
>>327
2022で設定変えたって書いただろ
あほなのか

340:デフォルトの名無しさん
24/11/08 12:18:22.14 F9yTI1pla.net
LPTSTR lptStr = L"テスト";


次ページ
最新レス表示
レスジャンプ
類似スレ一覧
スレッドの検索
話題のニュース
おまかせリスト
オプション
しおりを挟む
スレッドに書込
スレッドの一覧
暇つぶし2ch