◎正当な理由による書き込みの削除について: 生島英之 とみられる方へ:C言語なら俺に聞け 163 YouTube動画>1本 ->画像>2枚
動画、画像抽出 ||
この掲示板へ
類似スレ
掲示板一覧 人気スレ 動画人気順
このスレへの固定リンク: http://5chb.net/r/tech/1721137434/ ヒント: 5chスレのurlに http ://xxxx.5chb .net/xxxx のようにb を入れるだけでここでスレ保存、閲覧できます。
C99以降のC言語では、main関数が正常に終了した場合、 明示的にreturn 0;を記述しなくても、コンパイラが自動的にreturn 0;を 挿入することが規定されています。 これにより、main関数の最後にreturn文を省略することが可能になりました。 これまじ? いや省略できるのは知ってたけど 書かなくても言語仕様的に正しいってことなのでは
>>6 > 省略できる
これまじ? ってやってみたら省略できた。知らんかった。
ところで、main以外はどうなんだろう mainだけ特別って事なのかな?OSとも絡むし
>>9 retunr 0; が補われるルールは main だけの特別扱いだけど……。
関連する変な規則として C では関数の返却値の型が void ではないときに return せずに } に到達、かつ、関数の呼び出し元が値を使おうとするのは未定義ということになってる。
逆に言えば } に到達するだけなら OK ってことね。
C++ だと関数の返却値の型が void でないときに return せずに } に到達するだけで駄目という違いがある。
>>9 値を返さない関数ならreturnは省略できる
値を返す関数だと戻り値が不定になる
(多分コンパイルでwarningが出るか最近のではerrorになるだろうな)
そのくらい一度も試したことないのか?
CPUが最後に処理したアキュムレータの内容が 戻り値として有効になってるケースが多い 違う実装があったら教えてくれ
戻さないで自動的に挿入されるのならvoidでいいやん
>>12 CPUでも最適化レベルでも変わるのでその情報は無意味だ
素直にvoidにしとけばいいじゃん
>>12 じゃあお前に教えるために
これからそういうの作ろう
>>12 最適化が絡むとなんでも起こる。
GCC でやってみた。
https://godbolt.org/z/rzoEqdYWz インライン化と合わさったときはおそらく
「なんでもいいなら事前に適当な定数 (この場合はゼロ) に置き換えてええやろ」ということが起こってる。
インライン化を抑止したらそのときに入ってたでたらめな値になる。
CGCのサイクル
ヘッダーファイルインクルードする1行だけのプログラム見たことがある #include /dev/tty
エラー: #include は "FILENAME" または <FILENAME> が必要です
<>を入力すると消えるブラウザというか掲示板も流行ったなHTMLは糞だわ
大抵最初の開発者は誰かが修正してくれるだろうと適当な仕様で設計して、 その後引き継いだ開発者はなにか意図があるのだろうと思ってそのまま維持していくという悪循環・・・。
RustがCより速くなるベンチマークは見たことがない
Nim2.0のORCは明示的にオブジェクトプールを使ったプログラミングが必要ですが
ベンチマークがCより2倍以上速くなって、特にハードなリアルタイムシステム向け
のチューニングもできるようになってるみたい
https://zenn.dev/dum...icles/af2b2b9f8fd890 Nim2.0がCより2倍以上速くなって、しかもORCでメモリ安全も担保されているなら
Rustを使う意味がなくなると思うのですが、このベンチマークは本当なのでしょうか?
NimはCのソースコード吐けるからから、Nimの手動メモリ管理はCの手動メモリ管理と
同じとして、Nim2.0のORCで明示的にオブジェクトプールを使ったプログラミングと
比較した場合のベンチマークが2倍以上速くなってるからCより速いと言ってる
https://github.com/Araq/fosdem2020 人間がCの手動メモリ管理したプログラムだと限界があるNimのムーブセマンティクスの
アルゴリズムでメモリの最適化をしてるから、人間では到底太刀打ちできない事を証明
した論文があるオブジェクトプール版のNimから生成したCのコードは人間には書けない
Nim2.0のムーブセマンティクスの本当に優れた最適化とORCで明示的にオブジェクトプールでプログラミングすることによって、人間がCの手動メモリ管理したベンチマークより2倍以上速くできる
https://zenn.dev/dumblepy/articles/af2b2b9f8fd890 Rustを褒めて自尊心保つやつの次はNim版が出てきたのか
Nim言語の良し悪しは分からんが、メモリ管理に関しては理想的だわ ムーブ後のオブジェクトにアクセスするとRustだとコンパイルエラーで面倒な事になるけど、Nimは参照カウントを使って解決するので少し遅くなるだけだ そっちの方が絶対良い 気になる場合は後で直せる
>>34 だからなんだ?
Rustでムーブ後のオブジェクトにアクセスしてみろよ
>>33 どこにコンパイル時期にメモリの不正アクセス検知できるコンパイラーがあるんだよ
便利すぎないか
>>36 ムーブ(所有権の移動)の概念知らない奴かよw
RefCellのborrowとかborrow_mutがCより速い訳がないだろ
アセンブラ使ったことない子供たちにはわからんのだろ
Aiの時代にこんなレトロ言語に夢中になってる場合でもないだろ
ペイントソフト溢れた時代にエクセルで描いて絶賛される時代。
AIなんて究極的には予備知識なしで使えるようになるもんだろ いま必死で呪文を覚えてる奴らには気の毒だがw プログラムの学習はそれとは逆だぞ
AIにはアセンブラかCで書かせた方が効率がいいじゃん
今はアニメもCGで作る時代だけど、だからデッサン力なんて不要と言ってるのに近いなw
AIなら直接機械語書けそうだけど最低限人間がコードを読めるようにするためにCで出力するのが流行りそう
もはやプログラマはAIにどう質問するかだけが求められてる時代 ビックデータが前提なのはわかってるけどchatAIと画像AIはマジでオーパーツだわとても0と1だけで実現されてる技術と思えん・・・
>>48 Cやアセンブラを知らなかったらコンピューター自体が魔法に思えるんだろうなw
プログラム上での比較が、未だに変数2つの比較(if(A=B)とか )しかイメージ出来ないので AIのアルゴリズムどころか、2つのサイズの違う画像比較ってのさえどうやるのか検討もつかん・・・。
3Blue1BrownJapanのディープラーニング解説動画
VIDEO 現在chapter6まで和訳されてる(本家英語版は7が出た)
>>51 引き算してその絶対値が一定以内だったら同じとみなす
if(abs(A-B)<C){…
それぐらいならわかるだろ?
この世界もほぼ陽子と中性子と電子だけで出来てるのにこれだけ複雑なんだから0と1だけで複雑な演算出来ても不思議ではない
ようこちゃんとでんこちゃんは知っているけど 中性子って子は知らない
0と1だけじゃないけどな その他に位(くらい)という概念がある これによって無限の数を表現できる むしろ位の概念によって数が表現されている それさえ有れば記号なんて何でもいい
どこかの国だか村では両手の指の数以上を表現する言葉がないって話をどこかで・・・。
>>59 位の概念が無いから10までしか数えられない
位を考慮すると両手で1023まで数えられる
指を曲げる伸ばすの2通りとすると1023だが、指を完全に曲げる、伸ばす、半分まで伸ばす(曲げる)の3通りとすると3^10-1=59,048まで表現できるなw
>>61-62 人差し指と薬指を伸ばして、かつ中指と小指を曲げるのは難易度がやや高いぜ。
(親指を伸ばせば『グワシ』)
とりあえず、他人の投稿で言ってもいない単語や解釈を勝手に加えてマウント取ろうとするのはどうかと思うぞ。
lvalueに関してエラーが出るんだけど、どうしてこれがだめなのかわからないです #include <stdio.h> int main() { char s[] = "hoge"; char t[100]; while (*t++ = *s++) ; printf("%s", t); }
>>68 char *p = s;
char *q = t;
while (*q++ = *p++)
こう書けば通る。何故かはちょっと考えて ;
>>68 s の型は char[5] 、 t の型は char[100] だというのはわかる?
だけど式に出てくる配列は原則として配列の先頭要素を指すポインタ (この場合に型でいえば char*) に型変換される。
変換後に出てくるポインタは rvalue なのでインクリメントの対象に出来ない。
rvalue ってのは式の評価をする間に一時的に生まれて評価が終わったら消えるものなので
仮にインクリメント出来たとしても何にも使えない。
配列が勝手にポインタに変換されるっていうのが変則的で分かり難いポイントだけど
これは C を使ってたら避けようがない。
ポインタと同じ表記が使えるだけでポインタに変換されるわけではないぞ老害
char *s = "hoge"; char t[100]; int i = 0; while (*(t+i) = *s++) i++; sを配列ではなく、ポインタに変える、 tもポインタにしたいところだが、格納先確保が目的なら 先頭アドレスからのオフセット指定で格納する様に変更
それなら while (*(t+i) = *(s+i)) って書くかな
s[]、t[100]と書いたとき、sやtはメモリー上の特定の位置を指す ラベルのようなものなので書き換える事は出来ない。ポインタ定数とも言う。 一方ポインタ変数は、任意のアドレスを指す変数、変更も操作できる constとか、突っ込まんでください
>>71 規格には「型変換する」と明瞭に書いてあって変換しないと解釈できる余地はない。
色々教えてくれてありがとう s[]の先頭を指すポインタ*sを++で進めることができちゃったら s[0]もズレちゃうのでだめだってことだよね そりゃだめだわ
s[], t[100]; って宣言したなら、s[idx], t[idx] って使おうよ
>sやtは const constっていつからあったか知らんけど constない頃からsもtも*pや*qとは扱いが違ったんじゃね
lvalue の概念は K&R 1st の頃からあったよ。 lvalue という用語はちょっとどうなの……と思うけど。 Rust だと place と呼んでるみたいだね。
ポインタそのものを変えないやつと 指す先を変えないやつの書き方で 未だに迷うっていう
キーワードを並べる順序で意味が変わるのは迷うけど 順序をどうならべても良い場合もそれはそれでびっくりする。 int const long foo; みたいに変数を宣言して良い。 まあそんなことをするやつはいないと思うけど。
consr char*は本当はchar const*と書くべきなんだよね これでもコンパイルは通って同じ結果になる 読む時は右から読めばいい pointer to const char これだと指す先がconstなのが分かりやすい ポインター自体をconstにするには char* constとして、同じく右からconst pointer to charと読む 両方constは char const* const となるけど、最初のconstは左に書けるので const char* const とも書ける これが分かれば迷う事は無くなる
>>81 アセンブラにして考えるとわかりやすい char s[] = "hoge"; アセンブラの表現↓ s: .db "hoge¥0" char *s = "hoge"; アセンブラの表現↓ s_org: .db "hoge¥0" s: .dw s_org 上の場合書き換えようにもsには実体がない アドレス定義ラベルでしかない *ただし完全に最適化されると下も上と同じになる ここでいう sには実体がない、とはどういうことですか?
大元の質問が
>>68 なので低レイヤからの説明はあまり筋が良くないと思う。
エラーメッセージの意味を読み取れるようにならないから。
8ビットCPUのメモリ保護されてない頃だと 配列どころか、プログラムコードも書換できました笑
> sには実体がない、とはどういうことですか? 変数エリアに書き込まれていない数値、データ。 プログラム上で要求された時にコンパイル時や関数によってその都度作られる仕様・・・かな?しらんけど。 >91 >プログラムコードも書換できました それはむしろ”技術”扱いだったな。 サブルーチンでジャンプ先やIOポートを書き換えて・・・て。 昔はCPU等のバグ利用がテクニックだったけど、今じゃバグの温床、セキュリティホール扱いだね。
こんだけいて
>>77 くらいしかまともな回答者がいないとかひどいなあ
そんなのこだわっても結局関数の引数で配列型では渡せないんだからその程度は受け入れて慣れたほうがいい
ここは、「聞け」とはあるが、「回答する」とは書いていない
こっちが自然だろ t[100]を*(t+idx)なんてやる方が何の拘りだよ
配列は外部リンケージのときも注意が必要なんだよね あまりそういう使い方しないから、すぐにはピンとこないや
>>93 別にまともでもない
配列で定義してポインタで操作できるのがCの柔軟性だから
idxにこだわると簡単な操作を複雑にしかねない
> while (*(t+i) = *s++) これは、 > while (*t++ = *s++) ;これがエラーになるのは何故かと言う質問から始まったからです t++がエラーで、t+iなら大丈夫が理解できれば解決だと思う ポインタの理解というのは壁にはなりますが、 乗り越えれば意外と簡単です、がんばれ!
>>92 ありがとうございました(sには実態がない)
gcc -S test.c
で .s を出力して眺めてみると、そのような感じになっていました
最適化と、AT&Tのオペランドが逆なのに慣れず読みにくかったですが
"hoge" は「実体」が .data に置かれ、実行時にスタックにコピーされるのかと想像してましたが、実装がどうあれ、スタッフ上に "hoge" を置くための元を実体というのは違うと思いました
実際、"hoge" は .db でアロケートされず、4字は 32ビットの数値定数とされ、スタックに即値で転記されていました(実行時に生成されていました)
# とても伝わりにくいと思いますが…
誰も説明してなかったことに気づいた。 E1[E2] が (*((E1)+(E2))) と等価であるというルールがある。
それいにしえからのバカ発見器なんだが2024年になってもまだ動いてるとはC言語おそるべし
>>103 その自由度があるからC++でhtbl["key"]の様な事が出来る
Cじゃ意味ない仕様だけど、禁止する必要も無かろう
>>101 "hoge"は長さちょうど32ビットだから即値でスタックに書き込むようになってるということなら
最適化によってそこまで省略されてるわけでsに実体がない件とはあまり関係ないな
最適化オフにするかもっと長い文字列で実験してみては
>>106 ありがとうございます
もう少し正確に書けばよかったのですが、4字と '\0' の2回に分けて転記していました
また、hogeを長くして(10字くらい?)試すと、やはり 4字ずつ整数にパックして即値で転記していました
もっと長大な文字列試せば、別にアロケートされたそれをコピーするコードが吐かれたかもしれませんが、
>>92 の指摘通り、実体がなく実行時に生成されることを確認できたとして打ち切ってしまいました
C の仕様は抽象機械の動作として記述される。 抽象機械の動作をどのように実際の機械と対応させるかは自由で、見かけ上の動作が同じならどういう機械語になってもいい。 生成された機械語から言語仕様を理解しようとすべきではないよ。 低レイヤプログラミングするならどう対応付くか知る必要がある場合もあるのは否定しないけど……
その抽象機械の定義はしょせん後付け c言語のソースから生成されるマシン語の想像が付くようになるのはいいこと
>>109 機械語の想像がつくのが不要とも悪いとも言ってないよ。
そこから言語仕様を理解しようとすべきじゃないと述べてる。
できないから。
>>111 無用な心配
Xに溢れてるクソリプと同じ
>>108 ありがとうございます
そもそも
>>88 で sの実体がないとはどういうことか、というのが疑問だったためで、言語の仕様(というか実装)がどうかには着目していませんでした
printf("%s\n", s); が .sではputs(s); に置き換えられていたり
そうだよな~
この場合に限っては言語仕様としての理屈もあんまり違わんけどな。 ただ、正式な用語を知ってると細かいことを調べやすいみたいなのはあるので便利。
gccは配列に確保した短い文字列は最適化無しでもレジスターに載せてしまってるな ポインター文字列は最適化してもレジスターには載らない なので配列は配列として使った方が最適化で高速化される可能性があるという事だな
ポインター文字列って変な言葉だな。 この場の造語だと思うけど char *foo = "bar"; みたいなやつのことだよね? 文字列リテラルは静的記憶域期間 (寿命はプログラムの最初から最後まで) を持つオブジェクト。 どこかにある文字列をポインタで指しているという状況。 そのどこかにある文字は他のどこかから指し示されることもありうるので簡単には消えられない。 その一方で、配列の初期化子は配列を初期化する以外に使われる可能性がない。
>>93 それのどこがマトモなんだよ
>>94 の言い分の方が正しい
配列型が無いんだから
>>96 >t[100]を*(t+idx)
t[100]を100[t]
よりはマシ
>>97 だよな
>>119 んなこたーない
char foo[] = "hoge";
char* bar = &foo[1]; /* 敢えてずらしてみる */
printf("bar -> %s\n", bar);
で中身は何度も参照されるぞ
gccで試してみたら敢えてずらしてポインターに代入されたとしても、レジスターに文字列を保持したままprintfに渡すというトリッキーなコードが生成されたw
スタックに文字列を書き込んでそのアドレスを渡してるっぽい
短い配列文字列をポインターに代入したらレジスターに保持する最適化を諦めるかと思ったら、そうじゃなくて意地でもレジスターに保持したまま処理を進めるgccスゲーよw clangの場合はポインターも配列も常に静的に文字列を定義したものを使ってた
最近のCPUはレジスターに文字列格納できるんだな 何バイトくらいなら入るんだろうか
gccの場合だと64bitだと8バイトだから最大7文字かなと思ったらレジスターを複数使ってでも載せようとしてたw 取り敢えず50文字まで試したけど全部レジスタに載ってた でもこの辺はレジスタの空き具合にもよるのか?詳しくは分からん
スマン…間違えた…orz 正確にはアセンブリコードに書かれてると言うべきだった movabsq $3833745473465760056, %rdx movabsq $3978425819141910832, %rax movq %rdx, 40(%rsp) movabsq $3544395820347831604, %rdx movq %rdx, 56(%rsp) ↑こんな感じで文字列が直値で表現されてて、スタックに積んで使ってた だったら静的に確保した方が速い気がするけど、やっぱりレジスターから直接使う事が有るのか? 取り敢えずコンパイラーが出力するコードに深入りしない方が良いって事は分かったw
>>122 その場合に参照されるのは foo であって、 "hoge" というリテラルではない。
"hoge" は foo を初期化する以外の用途に使われていない。
>>127 データセグメントに確保するよりも
コードセグメントに書いたほうがすでにキャッシュに載ってるから高速なのかもな
速度の最適化か、生成されるオブジェクトの小ささかのトレードオフなんだろうね テスト用のコードは小さいから、後者は気にせずゴリゴリやってるのかな…
世の中CやめてRustにしろだとか OpenAIの新AIが競プロで上位1割のプログラマに匹敵とか言うじゃない 今更人間がCを続ける意義ってなんなんだろう
COBOLみたくロストテクノロジーを理解出来る貴重な人になれる
低レイヤに関わる資料が C を前提に書かれていたりするのは普通のことなのでたとえ C でプログラミングしなくてもある程度は身に付いてないと困ることはあるだろう。
>>128 初期化する以外に参照されてないってのはおかしいだろ
printfで中身が表示されてんだから
ポインター変数のbar経由で中身を参照してるけど、中身は初期化で渡された文字列そのものだ
そもそもリテラルが参照されてないという言い方もおかしい
リテラルは単なる定数の簡略表記に過ぎず、ソースコード上だけの用語だ
実行時に消えてると言いたいのか?
そんなわけない、全く消えてない
>>132 CobolやFortranはこれからも生き残るよ
多分
>>134 言ってることが意味不明。
textセグメントとかbssとかdataセグメントとか知らんの?
>>134 > printfで中身が表示
意味が解らん。
表示されてる中身というのは foo の中身であってリテラルじゃないだろ。
> リテラルは単なる定数の簡略表記
整数リテラルなどは右辺値だが文字列リテラルに限っては左辺値。
文字列リテラルは実行フェイズにおいてオブジェクトとしての性質を持つということ。 (抽象機械の上では。)
ただし、この文字列リテラルが型変換された結果によって生まれるポインタはアドレス定数の要件を満たす。
>>137 int i = 1;
printf("i -> %d\n", i);
この1は同じ様にリテラル表記以外に参照されてないというのか?
>>138 前述の通り整数リテラルは右辺値 (rvalue)。
文字列リテラルは例外的な存在だ。
まず、 C の用語では「オブジェクト」と「値」は違う意味を持つ。
メモリ上のビットパターンがオブジェクトで、値は式の結果だ。
(規格用語では data storage だがここではあえてカジュアルな用語で言うことにする。)
そして式の結果は lvalue と rvalue に区分される。
オブジェクトに結び付いている値が lvalue だと考えていい。
個々に規定があるので詳細は割愛するが、
式の中で変数名だとか単項 * 演算だとか [] とかがあればそれはメモリ上に存在してるのは明白だろ?
そういうのが lvalue 。
たとえば 1+3+5 みたいな式があれば途中で 4 という値が生じるが、これは「どこ」にある?
場所に結び付いておらず、式が終われば破棄されることになってる。
こういうのが rvalue 。
ちなみに lvalue も rvalue が要求される文脈では rvalue に変換される。 (メモリから値が読みだされる。)
>>138 このときの 1 というリテラルは (rvalue の) 1 を返す式で、その値が i にコピーされた後で寿命を終えて消滅する。
printf の引数の i で取り出される 1 は i に入っている 1 であってリテラルの 1 じゃない。
整数リテラルはあくまでも整数を返す (生成すると言ってもいいかも?) 式であって、メモリ上のどこかにあるオブジェクトというわけじゃない。
>>140 1は破棄されて"hoge"は破棄されないんだろ?
だから参照されてんじゃん
>>141 >>122 の bar が参照しているのは文字列リテラルからコピーされた配列であって文字列リテラルではない。
文字列リテラルが破棄されないこととは独立した話だよ。
>>142 barは配列のコピーじゃないだろ
ポインターなんだから
コピーしてるのはアドレス値だぞ
>>143 そのポインタが指しているという意味で参照してると言ってる。
なにを言いたいんだ?
論点は「配列の初期化子として現れる文字列リテラルは配列の初期化以外に使われる可能性がない」という話だろ。
> char foo[] = "hoge"; > char* bar = &foo[1]; /* 敢えてずらしてみる */ > bar が参照しているのは文字列リテラルからコピーされた配列であって文字列リテラルではない。 説明がよく分からないが、barは、fooではなく、どこかにコピーした別の文字列なり配列を参照していると言うことか?
>>145 bar はどうでもいいよ。 それは要らん間接参照を入れて例としてよくわからんようになってるから
飛び飛びになってる私の書いてることをあらためてまとめると
・ char foo[] = "hoge"; といったような記述があれば "hoge" によって foo を初期化する。
・ このときの文字列リテラル "hoge" は foo を初期化するだけに使われて他からアクセスされる可能性がない。
・ 言語規格の建前上は文字列リテラルの寿命はプログラムの最初から最後までだが……
・ この場合は他からアクセスされる可能性がないから機械語レベルでは文字列リテラルは最適化で消えて (即値としてコードに埋め込んで) も問題にならない。
つまり
>>118 でgccが文字列を即値にする最適化の条件を推察したら
はちみつ餃子が規格の観点で説明が不適切ってぼこってるわけか?
前者の情報のほうが有益だわ
>>147 補足したつもりだが。
どう最適化するにしても規格に反する挙動にしてはならない (したら規格に対応しているとは名乗れない) からどうしてそれで規格に反しないのかの観点から説明した。
最適化でどうなるかを考えながらC書くくらいならもうアセンブリ書いたほうが良いと思う
>>146 はちみつは文字列リテラルがアセンブリソースの段階で"hoge"と書かれてなければ消えてると思ってんだなw
例え命令コードの即値で書かれていても消えてる訳じゃないからー!残念!
だから話が噛み合わなかったんだw
まぁ強いて言えば、最適化でデータの表現法方を変えても構わないって言えば良い
x = 1; ← 最適化で消えても構わない x = 2; 最適化で消えても構わないってこういうことを言うんだよ char foo[] = "hoge"; "hoge"は消えて良い訳ないだろw gccは実際、命令コードに文字列を埋め込んでスタックに生成してるが、その文字列はポインター変数を使えば参照可能だ
>>149 それはそう。 原則としては言語の理屈に従っておくのが良い。
繰り返すけど、少なくとも初心者に対して低レイヤの観点で C を説明するのは筋が悪いと思う。
>>151 > 参照可能だ
その時参照してるのはスタック上にある配列であって、文字列リテラルではないってのを俺は何度書けばいいんだ?
文字列リテラルは本来は「プログラムの開始から終わりまでの寿命を持つオブジェクト」としてあらねばならないのが、
実際には文字列リテラルではない形になってることを「消えてる」と表現したのは確かに微妙な表現だったかもしれないが、
有るべき場所から消えてるんだからそんくらいわかるだろ。
そもそも最初は char* foo = "hoge"; との対比で言ってたんだから。
はちみつ餃子の説明はたぶん、C++ の考え方が混ざっていないか C で配列の初期化子に文字列リテラルが書けるのはあくまで文字列リテラル限定であって、それは式として扱われるのではなく、lvalue も rvalue もクソもないということだと思うが
>>154 初期化子の文法の一部であって式の規則の適用範囲外じゃないの?ってことだよね?
6.7.8 を見てこの場合でも式だと解釈してるけど、そういわれたらちょっと自信がないかも。
>>153 その配列に格納されているデータが文字列リテラルから生成された文字列(の実体)だろ
厳密に言いたいなら、文字列リテラルはコンパイル時に存在さえしてれば良いものなんだよ
何しろ「リテラル」だから
それを生存期間だの実行時の実体とごっちゃにしてるから訳分かんないことになんだよ
コンパイル時にさえ存在してれば良いという事を実行時には消えてても良いとか言っちゃってんでしょ?
char foo[] = { 'h', 'o', 'g', 'e', 0 }; 文字列リテラルは↑のシンタックスシュガーだ 初期化子は消えても構わないのか? 初期化子が生成した文字列は参照出来ないと言うのか?
>>155 https://en.cppreference.com/w/c/language/array_initialization ここ参考にしてたから文法定義の時点で式じゃないと思ってたけど、ちゃんと規格上は式としてのパースではあったね、すまない
改めて C99(でいいんだよね、6.7.8 ってことは)の draft 読んでみたけど、文字列リテラルで初期化できるのは 6.7.8.14,15 で特殊に定義された意味論であって、やっぱり式扱いじゃないんじゃないかね
>>154 結果的な挙動からするとどっちでも良いから書いてないだけかも。
皆拘らずに使っているのに言うのもあれなんだが C言語にはC++で言う参照はありません
hogeは破棄されないって一人がんばってるID:0gsw2riP0を救済して差し上げたいが……自分も完全にわかってないのでできない。
実在するのはfoo[]だけで 文字列"hoge"は破壊どころか最初からあっても無くてもいいというのがここまでにわかったことだろ
配列と別に文字列もどこか別に確保しといて何の意味があるんだよ この形で配列作る度に二倍メモリ食うことになるじゃないか
>>163 せやで。 だから最適化の余地があるという話をしてる。
>>163 clangは配列でも文字列リテラルは残ってるよ
ここって想像だけで語るアホばっかだなw
リテラルはコンパイル時のみに必要
それとは別に実行時にリテラルを実体化した値が存在する
基本的にrvalueだ
でないと当然初期化が出来ない
この値をはちみつは無視して語っている
はちみつはリテラルはコンパイル時にのみ必要な事と、実行時には必要な初期値(rvalue)を最適化で命令コードに埋め込む事を消えたと表現して、ごっちゃにしてるアホ これが結論
リテラルは参照されないと言ってるのがその証拠 そりゃコンパイル時にのみに必要なその場でデータ構造を表現するリテラルを、実行時に参照出来る訳ないだろw それが出来るのはコードをデータとして表現してるLisp だけだ C++のテンプレートでも無理 C++のconstevalなら可能になった std::formatはそれで実装可能になった 実行時には初期化の為のrvalueが絶対に存在する
constevalも文字列リテラルを参照可能なのはコンパイル時のみだった… やっぱり真に実行時に文字列リテラルを参照可能なのはLisp だけだな
>>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
>>167 起きていることは
>>127 でこれ以上なく具体的に説明されてるんだから改めて厳密に表現しないと理解できないとは思わなかったんだよ。
>>168 文字列リテラルが静的記憶域期間を持つことは 6.4.5 に書かれてる。
実行フェイズに存在するオブジェクトだよ。 (最適化を抜きにして仕様通りに解釈すれば。)
配列の初期化子として現れる文字列リテラルの扱いは微妙かもという話が
>>154 >>158 の指摘だが、
記憶域期間についての記述は文脈を指定せず文字列リテラル全部を対象にした記述に見える。
>>163 そりゃ書き換える場合があるからでしょー
一個しかなかったら関数呼ばれるたびに初期値も書き換わってしまう
なんで悩んでるのこの人?
constつけたら一個ですむだろ多分
>>171 > 実行フェイズに存在するオブジェクトだよ。
存在してんじゃねーかよ!
これが最適化で消えて良いかの話だよ!
gccの場合は命令コードに埋め込んでるけど、消えてる訳じゃないし、別のポインターから参照可能だ
>>173 配列とその初期化子として現れる文字列リテラルが別の存在だってことが俺が何度も書いてることだよ。
これがそんなに何度も何度も何度も何度も書かないと理解できないようなことか?
別のポインタは配列を指せるが、その初期化子として現れる文字列リテラルを指せるわけじゃない。
char* foo = "hoge";
のようなケースではポインタ foo は文字列リテラルを指してるということと対比しての話だぞ。
ちなみに「文字列リテラル」が「実行時」に存在してる訳では全くない はちみつはそこを勘違いしてる 静的記憶期間というのはスコープの事だ まぁエクステントと言った方が正確だが それはコンパイラーが理解できるものだが、それと「実行時」に存在する値を結びつけてはいけないし関係無い DLLだとしたら静的記憶期間の変数も実行時には存在しない可能性もある スレッドローカルストレージの変数もそうだな 要するに文字列リテラルで生成されたデータは実行時には確実にアクセス可能で、消えてるなんて全くあり得ない それをずっと言ってる
>>174 > 文字列リテラルを指せるわけじゃない。
はい、これが間違いの全て
文字列リテラルはコンパイラーだけが理解できる「構文」に過ぎない
それを実行時にさせないとはこれいかに?w
文字列リテラルは「実行時」には何て名前になってんだ?
配列でもないぞ
配列に代入される前のrvalueの事だ
まぁ文字列は例外的にlvalueにもなれるが、rvalueであることには違いない
>>171 なんかいろいろ書いたけど最終的には自分もそれで合っていると思う
実用上は正直どこで役に立つのかあまり思いつかないが、規格上どういう建て付けになってるのかはとりあえず理解できたかも
というか、実用上あんまり役に立つわけじゃないから今まで調べもしなかったというか
規格上は「リテラル」は存在せず integer/enumeration/floating/character は定数なんですね
それで定数は記憶域期間を持たない
文字列リテラルは静的記憶域期間を持つ
複合リテラルは関数本体の外か中かに応じて静的/自動記憶域期間を持つ、と
うーんでもなあ
某言語でいきなり &1 とか書けるの知ってたら別に定数にも記憶域期間持たせればいいじゃんとか思っちゃうなあ
とりあえずそうなっているというだけか
>>175 > 静的記憶期間というのはスコープの事
ちがう。 記憶域期間はオブジェクトの寿命の区分。
6.2.4 を参照のこと。
寿命の区分が設定されている以上はオブジェクト (メモリ上のどこかにある) のこと。
> 文字列リテラルで生成されたデータは実行時には確実にアクセス可能で、消えてるなんて全くあり得ない
関数 (C のプログラムは関数の集合なので実質的にプログラムの全て) はオブジェクトではない。
私が「消える」と表現したのはこの意識があったからだが、機械語のレベルでどこかには存在するという意味ではそりゃ存在するだろう。
(同じ内容が連続する配列だったらループで書き込むような形にすることもあるかもしれない。)
配列の初期化子としての文字列リテラルは本来あるべき場所 (オブジェクト) から最適化で消えてるし、ポインタで指すことは出来ない。
>>177 C++ の右辺値参照も左辺値参照も左辺値なんだよね。
参照を経由したら左辺値になるなら最初からそう出来ないか? と思ったことはある。
>>178 > ちがう。 記憶域期間はオブジェクトの寿命の区分。
だからエクステントと書いてんだろ!
もしかして理解出来なかったか?
> 配列の初期化子としての文字列リテラルは本来あるべき場所 (オブジェクト) から最適化で消えてるし
本来あるべき場所(オブジェクト)って何だよ?!
目茶苦茶だなw
これがコンパイラーと実行時に存在すべき値(rvalue)をごっちゃにした成れの果てだなw
初期化に使われた(文字列)リテラルが実行時にrvalueになったものに名前を付けるべきだな これは最適化でも消えることはない(当たり前だが…) 名前がないとまたリテラルは消えるから参照出来ない野郎が発生しかねないw
>>174 >char* foo = "hoge";
>
>のようなケースではポインタ foo は文字列リテラルを指してる
その表現が間違ってる。
fooは静的記憶域を指してるが正しい。
intptr_t *bar = 0xAABB;
この場合数値リテラルを指すなんて言わんだろ。
>>char* foo = "hoge"; >> >>のようなケースではポインタ foo は文字列リテラルを指してる > >その表現が間違ってる。 >fooは静的記憶域を指してるが正しい。 彼も文字列リテラルは静的記憶域に置かれると言ってなかったっけ 僕にはこの2つの違いが分からないや 勘違いだったらごめんなさい
>>68 規格に後置++演算子は実数型とポインタ型にしか使えないとあったけどそれの関係じゃないの?
規格でそう決まってるだけの話では?
ちなみに int main(int argc, char *argv[]) と定義しても argvは++できる
main の引数だけど、人によって好みがある *argv[]だったり、 **argvだったり、 さすがにargv[][]はいないと思う
>>185 配列はポインタに型変換される。 だから型は合うんだよ。
変更可能な左辺値でなければならないという制約に違反してる。
>>182-183 静的記憶域期間ってのは静的+記憶域期間なんだよ。 静的記憶域+期間じゃないんだよ。
まあ静的記憶域期間を持つオブジェクトが配置されている場所を静的記憶域と呼んでもカジュアルな場面ではそんなに不自然ではないとは思うけど。
実装上は専用のセクションに配置するのが普通だし。
ここまでのまとめ Cは生産性が低い C使いも生産性が低い
ID:+a4Swf1f0 は、言語に何使おうと生産性が低そう
>>191 ,192
生産性など、君ら社畜を計る尺度に過ぎんよ。
芸術家は、時間をかけて1行の美しさを追及するものだ。
>>189 変更可能な左辺値に配列型は含まれないからそれとは違うん?いつポインタに型変換されてんの?
>>194 6.3.2.1 より
> 左辺値がsizeof演算子のオペランド,単項&演算子のオペランド,又は文字配列を初期化するのに使われる文字列リテラルである場合を除いて,
> 型“〜型の配列”をもつ式は,型“〜型へのポインタ”の式に型変換する。
式として出てくる配列は一部の例外を除けば問答無用で変換されるので ++ のオペランドに配列が出てくるときも変換後のポインタ (rvalue) に対する演算 (実際には出来ないけど) として解釈されるということでいいと思う。
>>195 配列オブジェクトの先頭の要素で左辺値じゃないって書いてあるな
ということは左辺値の式の中に出てくる配列は左辺値じゃなくなっちゃうということ?
なんでそんな仕様になったんだろうね
>>196 C には配列の要素を指すポインタとは別に配列を指すポインタというものもある。
こんなことが出来る。
int foo[10];
int (*bar)[10] = &foo;
このときの bar の型は int(*)[10] ということになるわけだが……。
型情報として長さが含まれるのはかえって邪魔だ。
大抵の配列を受け取る関数 (str系やmem系など) は配列の大きさが固定ではないから。
配列の先頭要素で配列を代表させる (それが簡単な記法にする) ほうが都合がよかったんじゃないかと思う。
配列全体をひとつの値として扱いたい場合のほうが少ないだろうという判断もそれなりに合理的じゃないかな。
いまどきの言語 (Go とか Rust とか) は範囲を表すスライスという概念を導入して解決してるけど、
C の登場時期だと 2 ワードのオブジェクトを基本型にするのってなんかヤじゃない? と思ったとしても仕方ない。
>>190 横からすまんが、記憶域期間って言葉も変
>>189 >配列はポインタに型変換される。
それは関数呼び出しの場合だぞ
この糞コテは半端知識のかまちょだからNGやスルー推奨
>>199 こっちは根拠になる規格の文面を提示してるんだから違うというなら違うと思う根拠を提示して。
>>187 たしかに関数の引数だと違うんだな
https://ideone.com/MR7Vqm #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 は出来ない
https://ideone.com/xEP42d >>197 流石に言ってる事が的外れ過ぎるのでもうちょっと勉強した方がいいと思うよ
恥ずかしながら、静的記憶域期間(で合ってるのか?)という言葉を知らなくて、ライフタイムは「静的」に含意されているのかと思ったワ… しかし、記憶域期間って違和感あるなぁ
>>203 余談だけど配列だけじゃなくて関数型も関数ポインタ型に調整されるよ。
>>201 規格に配列は常にポインタに変換されるなんて書いて無いぞ。
>>208 「常に」とは書かれていない
「ポインタに変換される」ではなく「ポインタに型変換される」
>>102 がまさにそれでしょ
E1という配列が関数呼び出しでない場合においてもポインタという型に変換されているから出来ること
>char *hoge(char fuga[10]) こう書いてあっても、関数内で10を使う訳ではない 関数内で仮に100個めの要素アクセスするロジック書いてもエラーにはならない (実行時にはエラーになると思う、多分) だから、 >char *hoge(char fuga[]) 添え字無しにしても良いことになる
>>210 元々ローカルでchar hage[10];と定義して10以上をアクセスしてもコンパイル時にはエラーにならないでしょ
引数に[10]と書くとしたら可読性のため(この関数では[0~9]までアクセスする可能性があると明示するため)
__FILE__ とか __LINE__ は大文字なのになんで __func__ は小文字なん?
範囲の問題じゃなくて ++hage または hage++ が出来るか出来ないかが問題なんです
一見配列を受け渡ししているように見えるけれど、 実際はポインターとして受け渡ししているってことでしょ
>>212 __func__ はマクロではないからだと思う。
#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; }
>>214 そんなことは判ってるよ
(char hage[10]) で hage++ または ++hage 出来ちゃってる(ように観える)のが問題なんでしょ
関数の引数は (char hage[]) または (char *hage) のみにすれば良かった
(char hage[10]) はどうみても蛇足(結局境界テストされてないし)
問題だと思う人は、使わないようにしましょう 開発サイトでそういうルールを用意するのも手です
>>197 そもそもstr系mem系はアドレスを受け取るんであって配列を受け取る関数ではないっていう勘違いがあるんだけど
それはともかく大きさがどうのとかなんちゃらが都合がいいとか、本当にC言語でなんかプログラムを書いた事あるの?
>>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]に意味が出る
>>222 c faq 6.21 (英文が詳しい)
https://c-faq.com/aryptr/aryparmsize.html >>207 の'調整'は'adjust'だろう
N1256を'adjust'で検索するのじゃ
Look, a new day has begun.
8/16bit時代の1バイトでも、1ステップでも減らせってのを経験した人と 最近の可読性、移植性、安全性優先設計が当たり前世代とのギャップ。
ギャップの問題じゃねーから 文脈すら理解できないじじいはすっこんでろ
>>222 sizeof(hage) で配列のサイズが求まるの?
と思ったら、「char * (ポインタ)の大きさを返すよ」みたいな警告が @gcc
今どきの統合開発環境を使ってるなら変数の型くらい見れると思うけれど 古典的な手法としてあえてエラーにしてメッセージを読むという型の確認方法がある。 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* になってるのがわかる。
>>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]));
の結果ってどんな値表示されるの?
書式のとのuzじゃなくてzuだっけ?zだけでよかったっけ? ま、主旨はそこじゃないからいっか。
>>233 sizeof(char*)/sizeof(char) ということになる。
sizeof(char) は確実に 1 だから結果としては単に char* のバイト数ってことだね。
この場合は「『もし 10 に意味があるとしても』境界チェックはされないことに変わりないのでなんの役にも立ってない。 役に立てるとしたらここまで書かなきゃならない」というのが主旨なのであくまでもしもの話。
実際の値はどうでもよい文脈だと思う。
>>224 ああそうなの
昔のことだから記憶違いをしてたようだ
>>235 >>222 の「これなら[10]に意味が出る」ってのは間違いってことね。
'ここの10は意味ありませんよ' って警告を出してもいいじゃんってことでしょ それなら例えば typedef char HAGE_TBL[10]; void foo(HAGE_TBL hage) {} (毎回10とか書くのは危険なのでこういう使い方が多いと思う) などとした場合に毎回警告が出てうざいことになるんじゃないか
警告ならまだ笑っていられるが、 明らかに書いた奴の意図とは違って誤動作してるだろ
void aaa()の中で、 引数で渡された値が何かを確かめて見ると良い それと、 sizeof(hage)やsizeof(hage[0])の値も プログラム書いた人の意図としては、 sizeof(hage)/sizeof(hage[0])が10になるはずなんだが さてさていくつだろうか?
本人が新たなネタを出してくるんだもん。
>>238 でもわざわざ
typedef char HAGE_TBL[10];
ってやっておきながら、なんで
void foo(HAGE_TBL hage)
なの? 構造体と同じように
void foo(HAGE_TBL *hage)
ってしてみたら新たな何かが見えてこないかい?
cは洗練された型システム持ってないんだからそんなところ頑張っても無駄なんだよ この悟りに至って始めて脱初級 原則語るならそれからにしてくれ
Cは一部の洗練された型システム持つ言語よりも遙かに自由度が高い そこが分かってようやく中級レベル あとは本人の努力次第で空も飛べるし海も潜れる
おいおい そのぶん危険なんだから持ち上げる部分でもないだろ お前も初級
>>244 typedefは新たな型を作るわけじゃない別名を定義するだけから
void foo(char hage[10])
と
void foo(HAGE_TBL hage)
は同じことだよ
>>248 c言語ってとっくの昔から自由にキャストしまくれる言語じゃないの知ってるか?
さぁお前はなんと答える?
>>249 それが不満なようだから「HAGE_TBL * にしたら何ができるか考えてみては?」ということでは?
昔のコンピュータはメモリー少ないから、intで文字持つなんて贅沢だったんだよ
次のジジイの的外れな言いたいだけコメントを先取り intは16bit以上だぞ
違うよ、intは処理系依存だから8ビットの場合もある
>>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
https://www.open-std.org/jtc1/sc22/wg14/www/C99RationaleV5.10.pdf テンプレ入りキボンヌ
>>皆の衆
ともあれ、込み入った事情に該当しなければ
const char afoo[] = "hoge";
あるいは
const char * const ccfoo = "hoge";
場合によって
const char *cfoo = "hoge";
と書いて、うっかり書き換え防止に勇往邁進するのじゃ。
>>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)は同一で良いので、初期化を一回で済ませて後者の解釈。
結局、前後者両方の解釈が出来るようになっているように見える。
まだやってるキモ… いくら話題無いからってこれは誰も幸せにならない
ええんちゃう別に どうせ5chに答えを求めてやって来る人なんてもうおらんのやし
青い鳥を探してます ここに来れば教えてくれると聞いて来ました
PythonとかC++のスレで規格持ち出して言い合いしてるのを見たことないが 何故かここではよく起こるな
Cなんてのは対象CPUの違いとかでも標準とかけ離れた実装して来るのにね
>>269 君の問題点は規格読んでるの間違えてるとこだよ
>>271 規格を根拠にしてたら間違えてる箇所は間違えていると反論できるだろ。
根拠がないよりは良い。
ところでどこに間違いがあった?
>>235 これの1行目は文字列長によらず固定値にならない?
char* と char[] を区別できてないように思う
// これは (ヌル文字を含む) 4バイトのデータがスタック上に作られる
// sizeof(a1) の結果は文字列数により変わる
char a1[] = "abc";
// こう書いた場合、文字列の実体は静的な領域 (テキスト領域) に確保され、
// a2にはそのアドレスが渡される。
// sizeof(a2) はポインタのサイズであり、値は文字列長によらず固定
char* a2 = "abc";
char* でも char[] でも、a[n] と書けばn文字目を参照するのは変わらない これはポインタの [] 演算子は「ポインタをn個進めた位置の要素を参照する」ため、結果的には配列と変わらないから だけど前述の a1 と a2 は違う型なので、そこは注意が必要 たぶん VS Code でC言語の拡張を入れてれば、上記のように書いた変数のところにカーソルを当たるとヒントが出るので、それで確認できると思う それか実際に動かして sizeof の結果を見るか
>>273 > これの1行目は文字列長によらず固定値にならない?
その通りだよ。 固定値になってたぶん意図通りではない。
その話は
>>222 がボコボコに言われてもう終わったよ。
もう
>>222 を晒すのはやめてあげて......
あ、ひょっとすると
>>273 は話題を誤解してるのか。
「仮引数が配列形式だった場合にポインタに調整されるルール」が話題の中心。
仮引数として現れないと意味ない。
>>278 すまん自分が直近のレスだけ見て話題を早とちりしてた
だいたい流れは分かった
初歩的な質問で申し訳ないんだけど プログラムをユーザーの入力によって一時停止させるのってどうしたら良い? pauseで入力待ちにするとかフラグを間に挿入するとかではなくユーザーからの入力があった場合のみ一時停止したい
>>280 ソースコードの中にファイル名がpauseのファイルが存在するかを判断するロジックを追加
もし存在するならループに入りそれが消えるまで待てばいい
あとコンソールプログラムなのか? 環境を正確に書きな
>>280 C は言語として規定している範囲はかなり狭くて、細々とした制御には環境依存の方法が必要になることが多い。
ホスト環境によって作法が違う。
>>281 根本からなのね
>>282 初心者なもんで、一つのファイル内で完結したら嬉しいなーなんて
>>283 とりあえずコンソールで作ってる
環境はVS2022だけでおk?
>>284 ちょっと前古いサイト参照してたら環境違いすぎて苦労したし古い言語の宿命なんすかね
やりたいことがnon blockingでgetcharしたいってことだとするとwindowsだconsole apiを使う 例えばwindowsのreadline互換実装であるwineditlineを見るといい
>>287 一行目の通りで合ってると思う
念の為やりたいことを挙げておくと、メディア再生中の一時停止とかゲーム中のポーズ画面みたいなものだと思ってもらえれば良い
ただ、2行目のreadlineは日本語でググったりヘルプで検索かけたけどよくわからん
>>288 すごい簡単だね、これなら作れるかもしれない
入門書に記載がないのが唯一の不満だよ
>>285 言語の古さというより用途だろう。
低レイヤ部分を実装する用途に使う言語だから重厚なランタイムサポートを必要とする機能は入れられない。
いにしえの議論掘り返してすまんが、
>>182 の例示による説明が最も本質を突いてるように思う、感謝のレス
文字列リテラルは配列初期化子の構文糖でありながら、また文字列をも表すという二義性を持つ、という云うのはあくまで言語設計の為の汚いハックでしかなかろ?
気休めじゃなくて気疲れの間違いだろ 長さやsignednessでわけわからん変換しやがるバグの根源と言ってもいい
もともとバグってたのを対処療法で回避しただけじゃねーの? そんな驚愕するほどのこととは思わんな スペースは文字列に加えるってことだろ
char []s = "うんこ" s[20] = 0; // どっか判り難いとこにこんなのが紛れてる 回答「(sに)もっとスペースを追加して!」
どこか知らない国で "うんこ" が40バイトくらいある所があったりして
業務だとヨソの担当のモジュールに口出しするのがめんどいから対処療法で握りつぶすみたいなことはあるのかもしれん。
s("※んこ"の値)は読み取り専用になるんじゃないかな 処理系によるかもしれないけど
>「ここにスペースを入れてみて」「もっと沢山、もっともっと」 この辺りコピペ怪文書にしか思えないんだが 境界チェックしない言語ならありふれたバグだし、元文書はちんぽとかだったんじゃないだろうか
どうせメモリーリークだろうな データ位置を変えると現象が変わるなんて典型的だろ
おむつってあんま進化してないよな 吸収率だとか漏れだとかそんなのは上がってるだろうが、基本的な機能は変わらない 介護業界でも排泄介助っていう高齢者の汚物処理って割と大変な部類だと思うんだが そろそろおもつ革命を起こさないと業界崩壊するんじゃないの プログラミングでなんとかできませんかね
高齢者に限らず若い子でもうんこ漏らす時は漏らすし、そういう緊急時にも安心できるぐらいのものがそろそろ欲しいな 紙ベースで吸収率だとかで脳が退化してるおむつメーカーではおむつ革命はとても期待できないだろう
介護対象に飲ませるうんこがあまり臭くなくなる薬みたいな技術は進化してるぞ
薬で臭くなくしたうんこだからといって介護対象に飲ませるのはどうかと思うぞ。
>>295 こんなんじゃね #include <stdio.h> #include <string.h> #include <limits.h> int main(void) { char s[] = ""; // ←スペースを11個入れる sprintf(s, "%d", INT_MIN); puts(s); } 逆に考えるんだ。うんこはどうしても出てしまう。だったらそれはそのままにしておけ。 介護する側がそれを気にせず処理出来るのであれば問題は消滅する。だから介護者が それを気にならなくなるような精神に効く薬を作れば良いんだ。
>>295 って実行時エラーの話なのかコンパイル時エラーの話なのかもわからなくない?
NASAはネットなんてなかった1970年代にボイジャー1号打ち上げて 240億km離れててもプログラムを送受信してるのに俺らときたら
質問失礼 LPTSTR lptStr = TEXT("テスト"); って書くとE0144とC2044ってエラーを吐くんだがプロパティの文字セットって項目を設定なしにすると正常に処理されるのはどういう理屈なの? const wchar_t[]からLPTSTRに変換できませんってメッセージ出るし型が違うのかなと思うが だとしたら何故文字設定いじれば解消するのかもよくわからない
LPCTSTR ではダメですか? 当てずっぽうですが
>>323 そういうことじゃないのか、ごめんなさい
>>322 設定変えても依然エラーだが
VS Community 2022
>>325 2022だと設定項目見つからなかったから2012でやった、そしたら上記の結果になるんすよねえ
最近のVSはCの当たり前な構文が通用しないから困るよな
>>328 Visual Studio側の問題なのこれ?
>>327 2022で設定変えたって書いただろ
あほなのか
あと #define UNICODE #define _UNICODE だったかな
それでもだめなら 文字コードが違うんじゃないですかね
>>330 どストレートな罵倒は久しぶりに聞いたよ
高校上がってからは聞かなくなったけどね
>>331 ありがとう、だけどダメそうだ
文字コード関連のエラーなんだろうけどどうしたものか
char と wchar_t の不整合じゃなくて const の有無の問題じゃないの? C++ で文字列リテラルまわりの扱いで仕様変更があったからそれに関係してるのかも? C++ での文字列リテラルの型は const char[] (ワイド文字リテラルの場合は const wchar_t[]) だが、文字列リテラルから直接変換する場合に限り char* (ワイド文字リテラルの場合は wchar_t*) に暗黙に変換して構わないというルールが C++03 まではあって、このルールは C++11 で削除されたという経緯がある。 つまり C++11 以降は文字列リテラルから暗黙には const を剥がすことが出来ない。 (キャストを書けば出来るけど。) C では文字列リテラルの型は元から char[] で、 const が付いてない。 だから const まわりの制限とは関係ないんだが、これは C の仕様のほうがおかしいし、 C++ と同様の判定をしたほうが理に適っているとマイクロソフトが考えることはあるかもしれない。
E0144 エンティティの初期化 型”cont wchar_t *"の値を使用して"wchar_t *"のエンティティを初期化することはできません C2044は関係無い
>>336 なるほどね、LPTSTRがchar*だから代入できないって話になるのか
それがわかったらエラー文にかいてあることが理解出来るね
昔の仕様だとconst charに見えて実際は違かったってこと?
それなら今回のコードもエラー吐かないし悩まなくてよかったのに
>>337 関係ないの?LPSTRに代入できませんって言ってるように見えるけど
signedとunsignedでも怒り狂うからなぁw いいんだよ、こっちは中身しってんだから余計なエラー吐くなよ
>>338 > 昔の仕様だとconst charに見えて実際は違かったってこと?
C の規格としては本来的に文字列リテラルの型には const は付かない。
これは今も昔も同じ。 変更はない。
なので何かが変わったとしたらマイクロソフトの独自仕様。
私はそのへんに詳しいわけじゃないけど C++ の規格改定に引きずられた可能性は想像できるなぁというぼんやりした予想なので経緯はわからぬ。
でもまあ結果的に const の問題ってのは妥当なみたいだね。
LPTSTR lptStr = (LPTSTR)TEXT("テスト"); で警告出たりするのかな? 糞面倒だけどキャストで通るならそれ以上の対応不用
VS使ってるからたぶんCじゃなくてC++ こういうボンクラの自覚ないボンクラは相手しても疲れるだけ
>>341 理解した
constは付かないはずなのにリテラルにVisual Studioが勝手に付いてることにしてくるってことね
わざわざありがとうスッキリしたよ
>>343 そんなこと言いながら何回もレスくれるなんて
>>315 どっちもいける
実行時エラー
https://wandbox.org/permlink/r9w30EwoyKVxIguC > Segmentation fault
コンパイル時エラー
https://wandbox.org/permlink/yPJz2UPs8xHYPLAr > prog.c: In function 'main':
> prog.c:8:17: error: '%d' directive writing 11 bytes into a region of size 1 [-Werror=format-overflow=]
> 8 | sprintf(s, "%d", INT_MIN);
> | ^~
> prog.c:8:5: note: 'sprintf' output 12 bytes into a destination of size 1
> 8 | sprintf(s, "%d", INT_MIN);
> | ^~~~~~~~~~~~~~~~~~~~~~~~~
> cc1: all warnings being treated as errors
左辺をLPCTSTRにすれば良くない? リテラルの文字列を可変にすること自体が本来は不要だし、右辺を可変にキャストするよりは左辺を不変として (LPCTSTRとして) 受け取れば良いと思う
>>344 オンラインコンパイラで VS17.10 を確かめてみたが文字列リテラルには const は付かないぞ。
お前が間違って C++ を使ってるという
>>343 の意見に一票。
>>322 ・Microsoft Visual Studio Community 2022 (64 ビット) を使用し「C++コンソールアプリ」で新規プロジェクト作成
・ソリューションエクスプローラーでソースファイルにあるファイル名を*.cppから*.cへ変更
・ファイル名を変更したファイルに下記をコピペ
#include <windows.h>
int main(void)
{
LPTSTR lptStr = TEXT("テスト");
}
・ビルド(B)→ソリューションのビルド(R) でフツーにビルド通ったわ。
>>343 は速攻ぶったたいてるが、学生か初学者はこういう経験しとくもんだ
Cは汗に似て泥臭いんだよ
俺もあとで追試しよっと テキトーでやってて知識整理できてないわ
>>322 コンパイラオプションを見れば明らかになるじゃろう。
EchoAPIがVS Codeのワークフローにピッタリで、APIテストの能力がグッとアップしったって聞いて
Q. doubleをprintfで表示するには%lfでいいの? A. double 型を printf で表示する場合、%lf ではなく %f を使用するのが一般的です。 理由: printf の可変長引数において、float 型は double 型に自動的に昇格されます。 そのため、%f は double 型の値も受け取ることができます。 %lf は scanf で double 型の値を読み込む際に使用されますが、 printf では %f と同じ意味として扱われます (C99規格以降)。
これが同じ値書いてくれないのは普通だったんだっけ.
#include <stdio.h>
int main() {
int s=31;
unsigned long i = 1 << 31;
unsigned long j = 1 << 31;
unsigned long k;
while(i) {
k = 1 << s;
printf("%lu,%lu,%lu¥n",i,j,k);
i = (unsigned)i
>>1 ;
j >>= 1;
s--;
}
return 0;
}
手元にあるGCCとMS-C(32bit)は 同じ値が出てました
質問失礼します ダイアログボックスについて学習しようとしているのですが、サンプルのリソースをコピペしたところ、ダイアログボックスのIDが認識されなく手詰まりになってしまっています。 どなたかご助力ください。 TEST DIALOG (座標を書くと書き込みできない) C2059 C2061 以上のソースでエラーを吐いてしまいます。リソースをベタ打ちで記述する参考サイトが少ないので判断がつきません。
記述に文法上の誤りがあるって事です。 コピペで失敗しているのか、 元々のサンプルに誤りがあるかは これだけでは分かりません 文法の基本から学び直して 自分で見つけるしかないかもしれません
>> 358
試していただきありがとうございます.
FreeBSD clang version 18.1.6 (
https://github.com/llvm/llvm-project.git llvmorg-18.1.6-0-g1118c2e05e67)
Target: x86_64-unknown-freebsd14.1
と,gccは共に jの値がおかしいのです.
試しに,
unsigned long j = 1 << 31;
を
unsigned int j = 1 << 31;
にすると同じ値になる.
これはコンパイラのBUGかなぁ.
よく分からないけど unsigned long i = 1 << 31; unsigned long j = 1 << 31; を unsigned long i = 1L << 31; unsigned long j = 1L << 31; とするとうまくいく? clang どちらでも同じ結果になりそうだけど 見当違いだったらごめんなさい
gcc -S でアセンブラ出してみてみたけど、 いや、アセンブラよくわからないんだけど、 修正前の iと jは初期化時にいずれも符号拡張されて大きな値になっていて その後なぜか iの方は下32ビットで、jの方は64ビットで計算されているようで、正しいのはむしろ jのように見えたがごめんなさい 本当にアセンブラ分からないので多分間違ってます…
gcc, clang sizeof(int) == 32 sizeof(unsigned long) == 64 での出力 18446744071562067968,18446744071562067968,18446744071562067968 1073741824,9223372035781033984,1073741824 536870912,4611686017890516992,536870912 省略 8,68719476728,8 4,34359738364,4 2,17179869182,2 1,8589934591,1 これはこれで正しいと思うが
あ、iは unsigned (int)でキャストしてるのか
わかりやすく,intのものとcastかけたのにしてみました.
これだとやはり,pの値だけ変でした.
元々は,binaryで数を8bit 16bit 32bitで表示する関数が,8,16が普通で32だけ変なので気がついたのでした.なんでintだと符合拡張されなくてlongだとされるかが謎.
#include <stdio.h>
int main() {
int s=31;
unsigned long i = 1 << 31;
unsigned int j = 1 << 31;
unsigned long p = 1 << 31;
unsigned long k;
while(i) {
k = 1 << s;
printf("%lu,%u,%lu,%lu¥n",i,j,k,p);
i = (unsigned)i
>>1 ;
j >>= 1;
p >>= 1;
s--;
}
return 0;
}
unsigned long p = 1 << 31; を unsigned long p = 1L << 31; にしたら同じ値になりました. ううむ,なぜ unsigned int j = 1 << 31; だとうまくいって,longだと1Lにしないとうまくいかんのだ.
右辺が 1<<31だと 左辺が intだと0x80000000がそのまま、 longだと 0xffffffff80000000に拡張されて転記されるからでは
unsigned long i = (unsigned long) 1 << 31; とすれば iは 0x80000000になるかと
>>367 言語仕様的に解釈すると……
シフト演算子の結果の型は左オペランドを整数拡張した後の型と同じになる。
整数リテラルは int の範囲で表せる限り int なので 1 は int 。
int は整数拡張の必要がないので 1<<31 の結果の型も int 。
そして結果の型が signed かつ結果の値が結果の型で表現可能な範囲にないときの動作は未定義なので
2147483648 が int (おそらく質問者の環境では 32 ビット) の最大値である 2147483647 を越えていて未定義の挙動となる。
不定とか処理系定義ではなく未定義と明記されてる。
つまり言語仕様上は何が起きても良いということ。
6.3.1.3のこれじゃないの Otherwise, if the new type is unsigned, the value is converted by repeatedly adding or subtracting one more than the maximum value that can be represented in the new type until the value is in the range of the new type.
6.3.1.3 符号付き整数型及び符号無し整数型 整数型の値を̲Bool型以外の他の整数型に変換する場合, その値が新しい型で表現可能なとき,値は変化しない。 新しい型で表現できない場合,新しい型が符号無し整数型であれば,新しい型で表現しうる最大の数に 1加えた数を加えること又は減じることを,新しい型の範囲に入るまで繰り返すことによって得られる値 に変換する(49)。 なるほど,1がintで<<31すると負の最大値となって,unsignedとして表せないからか. 皆様,ありがとうございました.
>>372-373 いいえ。
シフト演算の段階で既に未定義を踏んでいるので型変換は関係ないです。
6.5.7 をご覧ください。
科学 + ンニュース 5ch
保守派もリベラル派も「自分の政治的信念に合致したニュース」を信じやすいという研究結果 [すらいむ★]
http://2chb.net/r/scienceplus/1732447647 コメントも含めて読むと
陰謀論が収まら無い理由が判明する
なるほど、32bitのみでやるときも1u<<31にしないといけないのか
>> 374 なるほど,そっちで既に未定義だったか. 6.5.7 ビット単位のシフト演算子 構文規則 シフト式: 加減式 シフト式 << 加減式 シフト式 >> 加減式 制約 各オペランドは,整数型をもたなければならない。 意味規則 整数拡張を各オペランドに適用する。結果の型は,左オペランドを拡張した後の型とする。右オペランドの値が負であるか,又は拡張した左オペランドの幅以上の場合,その動作は,未定義とする。 E1<<E2の結果は,E1をE2ビット分左にシフトした値とする。空いたビットには0を詰める。E1が符号無し整数型をもつ場合,結果の値は,E1×2E2の,結果の型で表現可能な最大値より1大きい値を法と する剰余とする。E1が符号付き整数型と非負の値をもち,E1×2E2が結果の型で表現可能である場合,それが結果の値となる。それ以外の場合,その動作は未定義とする。 E1>>E2の結果は,E1をE2ビット分右にシフトした値とする。E1が符号無し整数型をもつ場合,又はE1が符号付き整数型と非負の値をもつ場合,結果の値は,E1/2E2の商の整数部分とする。E1が符号付き整数型と負の値をもつ場合,結果の値は処理系定義とする。
VS CodeでEchoAPIを使うと、ツールを切り替えずにAPIテストをシームレスに管理できるようになったよ!
以下のサンプルプログラムが理解できず困っています。 該当プログラムは、コマンドラインから読み込んだBMPの色データを矩形として並べていくというものの一部を抜粋しています。 以下のfor文は カラーテーブルの数を取得する→ ブラシを設定する→ 先頭の構造体メンバからiCount先の構造体メンバを指定→ iCountにインクリメント という流れだと考えられると思うのですが、1に対し1カラービット分左シフトとなっている部分がどういったロジックによって数の取得が実現されているのかわかりません。 質問は2点あり、どのようにしてテーブル数を取得しているのか、コードの理解は正しいのかについてお答えしていただければと思います。 サンプルコード #include <windows.h> BITMAPFILEHEADER bmpFileHeader; BITMAPCOREHEADER bmpCoreHeader; RGBTRIPLE *prtColor; for ( ; iCount < (1 << bmpCoreHeader.bcBitCount) ; iCount++) { SelectObject(hdc , CreateSolidBrush( RGB( (prtColor + iCount)->rgbtRed , (prtColor + iCount)->rgbtGreen , (prtColor + iCount)->rgbtBlue ))
bcBitCountはピクセルあたりビット数で1,4,8,24だそう nビットで表せる値は2^n通りで、これは左シフト1<<nで計算できる
# 質問されていない部分だけど… iCountと比較する値はループ内で変動しないよね? だったら毎回計算せずにループ前で計算して別変数に記憶しておくほうがよくないかい?
ユーザーの犯したバグも直してくれるとありがたいなあ
シフトでも掛算でもどっちでもいいけど 質問者のように読んで悩むのは問題 コメント書いておけ ループ内毎回計算か最適化でループ外に出したかは コンパイル後の逆アセンブルとかで確認するの? だったら間違いないようにループ外に出す方が良い癖にもなると思うのだが
380の知能では最適化したつもりが新たなバグを埋め込む事になるかもしれん 自身の身の丈に合ったコードにしとけ 未来の自分が賢くなってる事を信じて
#include <windows.h> BITMAPFILEHEADER bmpFileHeader; BITMAPCOREHEADER bmpCoreHeader; RGBTRIPLE *prtColor; ↑ この間に何も描かれてないのは投稿者が勝手に削除したの?元から無いの? ↓ for ( ; iCount < (1 << bmpCoreHeader.bcBitCount) ; iCount++) { SelectObject(hdc , CreateSolidBrush( RGB( (prtColor + iCount)->rgbtRed , (prtColor + iCount)->rgbtGreen , (prtColor + iCount)->rgbtBlue ))
なんでこんなに読めないのか理由がわかった 変数名や字下げや「,」前のブランクなど 論理そのもの以前にコーディングの美しさが全然無い
この掲示板書き込むと、スペースやタブは消されちゃうんだよな。
だから綺麗に整形した状態でソース載せたいなら、
全角スペース使うしかない。
あるいはソース公開出来るサイトにアップロードして、
そのリンクを張るなりする。
そういうサイトは、
>>1 に書いてある。
美しさとか言い出したら自転車置き場の議論なるからやめとけ
python自体のスタイルPEP8に加えてCについてのPEP7も整備されているのに
https://peps.python.org/pep-0007/ あえてそれに背くコーディングをする理由が見つからない
GNUのへんてこコーディングも規約文章は整備されている
他人のふんどしででかい顔のpythonは存在自体がきしょくってぇ そんなもん使ってる奴の押し付けに従う気にはとてもなれないって感じぃ
自分の使ってるテキストエディタにコピペして整形を実行したら一瞬でどうとでもなるんだからどうでもいいだろ。
func(a , b , c ); func(a, b, c); 上から下への変換はインデントとは異なりやっかい
>>395 どんな古臭いフォーマッタを使ってるんだ?
>>381 シフト演算を行った場合、10進数の1に対して乗算を行うわけではなく、2進数に対して行うという認識で良いでしょうか?
すなわち、この場合を10進数で表すと、1ではなくて2に対して、1,4,8,24、のいずれかを冪乗し、何通りの色の組み合わせがあるのかを確かめることができるというわけですね。
>>382 コピペしただけなのでとりあえず理解をと思い書き込みました。自身で書くときはそうしたほうがわかりやすいかもしれませんね。
>>385 少し別添えで記述されてはいたのですが、それだけでは理解に至らなく書き込みした次第です。
>>386 そうなんです、私も身の丈に合うコードにしたいのは山々なのです。
ところで、初級者向けのGUI作成の手引書を教えていだだけませんか?もちろん、ここ5年以内の環境で
>>387 勝手ながら削除しています。素人考えなのは承知です。
仕事柄、利権や法にはうるさくあらねばなりませんので、リスク回避です。
Cは知っといた方がいいけど GUIをやりたいならこのスレに居るのは時間の無駄なんだが そのBITMAPなんちゃらも以下の環境では気にしなくていい GUI開発おすすめ言語 iOS macOSアプリ Swift、Objective-C Androidアプリ Kotlin、Java Webアプリ Kotlin、Java Windows C# なおWeb系はHTML/CSS、JavaScript/TypeScriptは必須と思って頂きたい
Windowsの内部構造を知るのは時間の無駄なのか
BITMAPなんちゃらに詳しくなった所でWindowsの内部構造を知ったことにはならないんだがぁ? 現行Windows11の内部構造なんてきしょすぎてそもそも知りたくもないわ
これだけ見て分かるわけ無いよ max = 1 << bmpCoreHeader.bcBitCount; for (iCountの初期値が無いよ、普通0からだよね; iCount < max; iCount++) { // テーブルRGB値をブラシの色に設定? brush = CreateSolidBrush(...); // RGBで色指定したブラシで塗る?hdcが変わらんようだが何回も呼ぶ意味があるの? SelectObject(hdc, brush); // これ以降があるのか… }
bmpCoreHeader.bcBitCount の範囲チェックが必要そう uint64_t max; max = 1 << 64; // max == 0x8000000000000000 で意味がありそう max = 1 << 65; // これ64bit整数の範囲超えているよね、プロセッサ依存の値になる予感
64bitシフトでも溢れた これ難しいね uint64_t seed, max seed = 1; max = seed << 63; // 0x80000000 で期待どおり max = 1ull << 63; // 0x80000000 これも期待どおり max = 1 << 63; // 即値1のレジスタ範囲が足りない? max = 1 << 63; // 即値1だと32bitなのか
カラーパレットを使うのは1,4,8って決まってるんだが
1, 4, 8以外のエラー処理が無ければ手抜きプログラムだよ
>>407 理解してる俺でもデバッグん時に面倒だから使わない
スマホ世代もCってるなんて頼もしい限りだな
>>415 アマゾンにあった
「 モバイル C { C/C++ コンパイラ } 」だって
¥1,546
/dp/B00MFXHPBW
無料版もあるみたいだ。違いは分からなかった。 /dp/B01CEZQGX8
なんかEchoAPI、さまざまなAPIシナリオをモックするのに役立って、フロントエンドの作業を独立して行えるようになるよ
前はAIDEってのもあったような 自分も購入済みだったけどストアから消えた
>>418 ならただの宣伝マルチポストなのでさっさとNGしておくように
char text[32] = "count=" sptintf(text, "%s%d", text, 100); ↑これって問題ない?
>>421 sprintf のことだよね?
問題はある。
領域が重なるオブジェクト間でコピーが行われるときの動作は未定義とするという仕様になってる。
それと関数シグネチャを見ればわかるが引数のところに restrict ってついてるでしょ。
その性質上、他の引数がこれと領域が被ってはいけないというサインだ。
まあ引数を使わない関数であれば restrict 修飾されたポインタが指す領域がかぶってもただちに違反ではないが、常識的には渡す以上は使われるものと想定すべきだよね。
>>421 問題ありだ。1行目末尾にセミコロンがないじゃないか
あと、学校の宿題の答えをこんなところで聞いちゃいかんぞ
最近の小学校ではこんな宿題出るのか 末恐ろしいと言うか、頼もしいというか
コンピュータの授業とか普通にあるんだろ?今って 俺からすると羨ましい限りだわ でもダンスの授業はいらん
元々芸術科目や体育は面倒な存在だし ダンスはそれらが合わさって一見最強に見えるだけで専門科目に比べれば実は大した内容じゃない 子供は加減の付け方を知らないから物凄い壁に見えるんだろう
1990 年代頃なら中学校でコンピュータの授業はあったがプログラミングがちょっとでも出来るようになるほどではなく使い方に慣れるという程度だったと思う。 ただ、学校に設備や資料はあったから興味があれは詳しくなれるチャンスはあった。 設備をどのくらい解放するかは学校の体制によるだろうけど。
科学 + 5ch
【AI】AIはわずか2時間の対話で人間の性格をコピーできる [すらいむ★]
http://2chb.net/r/scienceplus/1733576027/ コメントに面白いことが書かれている
2時間で初等教育から大学院レベルまで学習完了したら 人間要らなくなりそうだな
>>429 たしか教師がクソすぎて失敗したんだよなw
やがて全ての仕事がAIに直結されたロボットによって置き換えられ、人類絶滅。 地球はAIのみが存在する世界になり、真空でもそのまま動くロボットが宇宙征服。
チェックボックスとかラジオボタンの状態を保存したいんだけどなんて調べればええんすの? 現状ウィンドウを破棄する前にコントロールの内容を取得して状態に合わせた変数を初期化ファイルに保存、再起動時に変数に対応した状態に再設定するみたいなのしか思いつかん 冗長になって見づらいだろうし代替案を知りたい
www最近、EchoAPIを使い始めたところ、効率的なAPIテストツールを提供してくれるおかげで、開発プロセスが向上した!
対応表をだーっと並べる、control_state_read_and_write(bool is_write, ...) みたいな関数を置く、など 割り切ってしまえば工夫のしがいはある ただ、そのときはよくても、あとになってみたら黒魔術でしかなかったりする 愚直なのもいいぞ
>>435 何がどう"冗長になって見づらい"のか?
これでなんか機能した TCHAR buf[255]; this->GetWindowText(title, 255); int len = _tcsclen(buf); _sntprintf(buf + len, 255, " %d", uiWindowCount); this->SetWindowText(buf);
this-> ナニコレ もしかしてC言語スレでC++使えるぞあぴーるですか! すげー
>>443-444 もし C++ の話なら上述 (
>>424 ) の restrict の説明が役に立たない。
C++ に restrict は無いから。
API自体はC言語なんでそこらへんはスルーでお願い
>>447 C の snprintf と C++ の snprintf は違うという話をしてるんやが
(最終的に同じものが呼び出される実装の場合はあるにしても。)
最近のRESTful APIについての議論に触発されてEchoAPIを試してみたところ、エンドポイントのシミュレーションツールがテストプロセスを非常に効率化してくれました。
MSは採用していないのかな? なんでこんなにバグが多いんだろう
1つめのプロシージャで宣言した変数を2つ目のプロシージャで使うって頑張れば可能? それともグローバル変数宣言したほうがいい?
>>452 それも考えたんだけど、プロシージャ作るときライブラリ側が指定した引数以外渡せないんじゃない?
そのプロシージャーを同一モジュール内lに記述して、 変数をスタティック宣言する、とか
>>454 そんなことできるんかよ知らなかった
{}内かつ、他のswitchと干渉しないところにベタ書きすればいいってことよね?
ちょっと違う様な気がする そのファイル内にある全ての関数から参照出来る宣言です スタティック宣言を調べて見て
>>456 ごめん、スタティックはわかってる
モジュール内への記述の方
言葉足らずですまん
調べてみたけど関数内に別の関数の処理はかけないっぽい? とりあえず自前のソース書き換えてみたけどC2275が出てしまう
モジュールとかプロシージャはc言語の用語ではないよ 誤解を生むからなるべく正しい用語で あるいはソース書け
Cで作ったソフトにアイコンをつける方法ありますか? コンパイラはmingw
>>460 リソーススクリプトを書いて windres コマンドでコンパイルしてリンク。
>>462 windows の話?
ウィンドウプロシージャにデータを結びつけたいのなら必要なのは SetProp じゃないかな。
>>458 よくある質問に書いてあんだからそれを読めよ
今北 何のデータかわからんが、だれに属しているデータなのやら 「全然関係ないところ」には、置かないほうがいいぞ少なくとも
下記のコードのsizeof(buf)/sizeof(TCHAR)ってなんの意味があるの? ただのsizeof(buf)じゃだめ? static int num; TCHAR buf[8]; stprintf_s(buf,sizeof(buf)/sizeof(TCHAR), TEXT("%d"), num);
>>466 自分の知識だと外に置くくらいしか思いつかんかった
TCHARは_UNICODEのマクロの定義の有無によって16bitまたは8bitになる
>>467 > ただのsizeof(buf)じゃだめ?
だめ。
TCHAR はコンパイル時に ANSI モードか Unicode モードかで定義が切り替わる。
ANSI モードのときは char で Unicode モードのときは WCHAR と同じ。
_stprintf_s も ANSI モードのときは sprintf_s に置き換えられて Unicode モードのときは swprintf_s になる。
swprintf_s のときの第一引数は文字数 (この場合は UTF-16 でのコードポイントの数) なのでバイト数である sizeof(buf) を渡しても駄目。
ANSI モードでしかコンパイルしないのであれば別に割らなくても大丈夫だけど、それならそもそも切り替えを前提としたマクロを使う必要ないしな……。
Unicodeになるとなんで割る必要が出てくるのかいまいち掴めないなあ BuffのサイズをTCHARのサイズで割ってどうしてサイズが出せるの?
>>472 ごちゃごちゃ考えてないで
とっととデバッガ使って値を確認しな
配列の大きさを得るために配列のバイト数を配列要素のバイト数で割るのはごく一般的なイディオムなので何がわからないのかわからない。
これらのアイデアを実装するために取り組んでいる中で、EchoAPIが設計ワークフローを本当に効率化してくれた
>>472 Unicodeの場合、2バイトで1文字を表現
①①②②③③④④⑤⑤⑥⑥⑦⑦⑧⑧⑨⑨ で9文字、18バイト
ANSIの場合、
①②③④⑤⑥⑦⑧⑨ で9文字、9バイト
> sizeof(buf)/sizeof(TCHAR)
sizeof(buf)が指すのはバイト数、Unicodeなら18、ANSIなら9
sizeof(TCHAR)が指すのは1文字のバイト数、Unicodeなら2、ANSIなら1
そして stprintf_s の引数 sizeOfBufferはバイト数ではなく「格納する最大文字数」であること
引数がバイト数ならsizeof(buf)でいいけど、引数が文字数を求めているならsizeof(buf)ではおかしくなる
上の例で言えば、Unicodeは18バイト9文字で本来は9とするところを18と指定してしまうことになる
すると関数側はバッファが18文字分(バイトで32バイト)あると勘違いするわけでバッファオーバーフローを起こす
sizeof(buf)/sizeof(TCHAR) は18バイトの領域があって、それを1文字のバイト数で割って「9文字」ということ
丸付き数字自体が1文字1バイトって意味じゃないからな 内部表現を表すために使用しただけで数字がx文字目として見て
>>476 朝わかりやすいね
でもANSIって1バイトと2バイト混合できるよね?どうなっちゃうんだろう
>>482 ANSIはバイト=文字数
そもそも論理的な文字数じゃなくて処理単位での文字数ね
だから strlen("あいう") = 6
strlen("123あ67い0") = 10 // 数字は半角(1バイト)、ひらがなは全角(2バイト)
Unicodeの場合でも正しい文字数になるわけじゃない、サロゲートペアの場合に文字数は2(4バイト)になる
Unicode だとサロゲートペアを脇においても異体字だの合成だのといったものがあるし、人間が紙の上に書くときの直感的な感覚で言うところの「文字数」とは定義が違うので、各文字コードの仕組みを知っておくしか仕方がない。
>>483 >>484 つまりこの方法だとコンパイル時に気をつけるしか無いってことか、大変だね
テキストエディタみたいなの作ろうとすると禿げ上がりそう
文字コード問題よりC言語で作れってほうがハゲりそうだ
>>485 方法が大変?
お前まだ理解できてないぞ
一般論として文字コードの扱いは大変だがTCHARの仕組みは単純だ
CがC++だったとしても変わらんでしょ VSCodeはレンダリングの都合でWebルレームワークとjavascriptで作られてるからC/C++製エディタと比較して遅いというデメリットがある
c言語で文字列処理はクソ面倒でしょ ライブラリの整備からやる必要がある上にコードがとっ散らかる
Windowsの場合使用フォントに応じて描画幅を返すAPIに丸投げできるから大した手間にならないが メモ帳の「右端で折り返す」相当を実装する場合右端のどこで切るかでその人センスが露になる
>>480 何か誤解があるみたいだが開発言語にCを選ぶようなやつがそんなのを面倒に感じる事はないんだよ
アプリケーションを作るにあたって TCHAR が必要になる状況はそれほどない。 Unicode 対応をきちんとやるならそれとは別に ANSI 版も作るという必要性はないし、両方を作る必要性がないなら切り替えを意識する必要もないから。 最初から WCHAR で書けばよい。 ライブラリとしてまとめるならどちらにも対応したほうが良いこともあるかもしれんけど。
テキストエディタ、アセンブラで作った奴いるだろう ハゲてはいなかったと思う
>>483 strlen("123あ67い0") == 12 // utf-8
>>497 Unicodeで文字列の長さって何?
書記素クラスタか?
って突っ込まれるから知ったかぶらないほうがいいぞ
>>498 文字数を数えられるように自分で書いたのだけど?
文字数数えられるけど知ったかとは?
>>499 それがまさに知ったか
unicodeの基礎すらわかってない
そんなやつのライブラリなんで誰が使うんだよ
>>501 基礎ってなに?
ただ文字数数えれるプログラムとしてだしたのに
>>502 それは書記素クラスタか?ときいてるだろ
でもその言葉の意味がわからんのだろ?
>>503 なんで書記素クラスタって言葉にこだわってるの?
もしかして教科通りにU+数字じゃないから言ってるだけ?
>>505 1文字 3バイトみたいだね
ソースを変えて出力してみた
退勤前に
>>497 見て、
ああ、"フロッピーディスク"って入れたら8が返り、"ハードディスク"って入れたら2.5が返るような関数だろ。
って思いつつ帰宅したら、またお前らときたら
>>509 自然言語がぶっ壊れてるんだよ。
Unicode は自然言語のぶっ壊れをどうにかこうにかコンピュータで扱える形にしただけ。
最近のRESTful APIについての議論に触発されてEchoAPIを試してみたところ、エンドポイントのシミュレーションツールがテストプロセスを非常に効率化してくれた
IsWindowVisible IsWindowEnabled EnableWindow のダイアログ版教えてくりゃ
%*d こんなの初めて知った B1.3 Formatted Inputに載ってたけど読んでなかった
(s)scanfのフォーマット引数もパターンマッチのように使えて便利だったり
>>519 俺はそれ20年以上前に知ったような気がする。
フォーマットの文字列をわざわざ別に作らなくて済んで素晴らしいと思った記憶がある。
円周率って math.h とかに入っているの? それとも pi = 4.0 * atan(1.0); とかで持ってくるものなの?
>>524 言語仕様にはないが、処理系によっては有ることもある。
特定の環境でコンパイル・実行できればよいならそれを使えばいいし、そうでないなら工夫も必用だろうし……
どのくらい移植性に配慮するかによるんじゃないの。
double の精度が有限な以上は無理数を誤差なく扱うのは不可能だし、どうしてもやりたいなら数値計算ではなく解析的な計算をするしかない。 ただ、工学的な用途だと誤差をゼロにする意味はあまりないことが多くて、誤差の程度が保証されることが需要。 たとえば分子一個分より小さい桁の部分で正確でも何にも使えないから考えるだけ無駄でしょ。
ちょっと解析的な計算というのが正確にわかっていない 数値的な計算というのは有限差分法とか用いて近似的な解を求める方法だよね? 解析的な計算というのは a *x^2 + b * x + c = 0 なら手計算で解けるよというやり方? 使ったこと無いけどマスマティカとかそういうソフトだっけ?
>>527 そう。 要は数式の変形で解くやりかたってこと。
どのくらいのものを扱いたいかによるけど四則演算と巾乗くらいからなる簡単な式を扱えればよいなら C で書いてもそれほど高度というほどではない。
リスト構造を作って切り貼りするってだけなので。
とはいえ、計算を始めたいときにやる下準備としてはかなり面倒臭いだろうとは思うけど。
なるほどね、解を公式化しておいて虚数が必要か判定する感じだろうね
πをπのまま計算して最後にmπで出力してくれれば良いのにと思うことは多い
数式処理の基礎の基礎ならこのあたりがオススメできると思う。
C言語による標準アルゴリズム事典
https://gihyo.jp/book/2018/978-4-7741-9690-9 Cの糞仕様でmath.hインクルードしてなくても int hoge(int) って解釈されるから 本当は double hoge(double) だったり float hoge(float) だったりしても コンパイルだけ通ってリンク後に問題起こすってのが昔はあったな
error: implicit declaration of function 'hoge' にならないの?
1のサンプルコードでコンパイル通らなかったから2のコードのようにキャストしたんだけど動き的には同じだよね? 1,pStrIndex = malloc(sizeof(TCHAR*) * count); 2,pStrIndex = (TCHAR**)malloc(sizeof(TCHAR*) * count);
>>533 厳密に言うと extern int hoge(); と暗黙に宣言したかのように扱うルールだった。 C89 では。
C99 で削除されたルールだけど今でも警告付きで通してしまう処理系はあるな。
>>535 C では void* から他のポインタへ暗黙の型変換が許されるが C++ では許されない。
コンパイルエラーになってるならたぶん C++ を書いてる。
(処理系によってはオプションでエラーや警告を制御できることもあるけど。)
二次方程式を式変形で解くのは「代数的」な解法な気がする 「数値的」解法はコンピュータ利用?、「解析的」解法?
「二次方程式を式変形で解く」の意味が ax^2+bx+c=0 の解 α, β をそれぞれ a, b, c の式で表す という意味なら代数的解法か?単に構文解析の気もするが α, β を浮動小数点数(複素数を含む)で表す という意味なら数値的解法か?解析的解法か? 単に解の公式に代入してるなら解析的解法の訳が無い罠
元の発言はたぶん円周率を近似値に置き換えないぐらいのことが言いたかっただけでしょ 5chのコテハンなんだからたいして考えてモノ言ってるわけじゃないだろうよ
奥村先生のアルゴリズム事典に二次方程式を解くコードが載ってる 解の公式だけで解くと桁落ちが生じるので解と係数の関係も使ってる。
コンピュータのマシン語は高級言語で言うところの「変数名」による識別子は存在しない なにによって識別するかは レジスタの固有名詞か メモリでの記憶場所を示すメモリアドレス メモリアドレスを記憶させる変数やレジスタを 特にポインタ変数やポインタレジスタと呼んでいる
ポインタには型があってだな、 intとか自分で定義した構造体とかの型が ポインタが指すアドレスを起点にそれらの型(ポインタの型)が配置されているかのようにメモリにアクセスするできるようにすることだよ アドレスには型がないけど(変な言い方だけど)そこにintがあるとかFILE構造体があるとか、そこにその型があるとしてポインタが指すからある そうでなければただのバイトの列 intとかcharなどのプリミティブな型でなく、構造体からイメージした方が分かりやすくないかな
そうだね p++ で数値が sizeof(*p)増える
CもだけどC++やJavaなり関数や変数、メソッドやメンバーを参照できる範囲を絞って 安全を確保しようとしているよね でもコンパイル後の実行コードで関数や変数のスコープチェックとかしていないしできないよね スコープがどうであれポインタ経由で場所がわかっちゃうんだし 無能プログラマの糞コード避けにはなるけどマルウェア対策にはならないということかな
>>546 ポインタをテーマにした本がある。
丁寧に説明しようとすれば本一冊分程度の分量は語れるってことだ。
それを掲示板で書ける程度の分量でより分かりやすくするのは無理だよ。
まずは入門書を読んだ上でわからないことがあれば具体的に質問して。
ポインタがすっと理解できない人はC言語は向いてないと思う
メモリの番地を直接指してるってだけの話なのに文法が意味不明なのが悪い
Basicみたいに配列で操作すれば分かりやすいぞ 笑
前橋和弥って人の本読んで理解した 長らく絶版だったようだが後継本がある
>>559 私もあれで学んだ ドロイド君みたいな表紙の旧版
わかりやすいと思う
ポインタには殺傷能力があります。 使う人は銃器の取扱免許が必須です。
だからさぁ 変数や関数スコープって アドレスでアクセスされたら アクセス拒否できる仕組みは無いよね?
さすがにセグメント違反は弾かれるぞ まあ、CPUやOSの機能だけどな
雑談として いろいろチェックのついたポインタがあっても、それをOFFにできれば問題ないんだぞ スピードの要らないところにもCは使われているので、そういう部分は、「ごてごて」でもいいんだよ
いやポインタのはなしをしたいのではなくて 高級言語で設計制限を行うことで可読性や設計ミスが高まるという言説があるよね 構造化プログラミングやオブジェクト指向の類 でも実際稼働するのはコンパイル後のマシン語で gotoというかジャンプ命令もあれば プライベートへのアクセスを実行時にチェックする機構とか無いわけでしょ 不具合調査はソースコードも大事だけどマシン語の流れも追わなけば 本当のところはわからんよね 更には投機実行や分岐予測もあるわけで 実際の稼働はソースコードによらないしマシン語とも異なる可能性が存在する
え? 最終的にCPUはマシン語として解釈して動くだけだからなぁ 人間がどう捉えようがそこは変えようが無いんだ
例えば goto文を可能な限り排除して構造化プログラミングというものが提唱されてきた でもコンパイル後のマシン語にはむき出しのジャンプ命令が使われる 構造化されたループや分岐も実際はジャンプ命令 処理のトレースでもデバッグでもソースコードとマシン語と両方追う必要があるが goto文を排除した理念の意味が… ソースコードは見やすいがマシン語はそうではないよね?っていう愚痴のようなもの
むき出しのジャンプ命令... 赤裸々なMovとか、一糸まとわぬAdd とか。
コンパイラひバグが無いかぎりは高級言語のソース通りに動くから大丈夫だぞ 昔のファミコン並みに処理ステップ数に要するクロックを数えてラインスクロールさせるとかでもしない限りタイミングも気にする必要無いし
むしろマルチコアの問題のほうがでかい 自分も、高効率に書ける自信がない
C言語に限らずJavaでもPythonでもLispでも最終的にはブランチしまくりヒープアクセスしまくりなマシン語で動いてるんだから心配しても意味ない。 たまたまC言語はマシン語に近い距離にある言語なのでマシン語「でも」デバッグできてしまうだけの話。
コンパイラ最適化の時点で追うのが難しい ましてや投機実行とくると…
思い出した continue や break は優遇されている印象
Pythonだって安全じゃないしな 俺この間自作したPythonプログラム動かしたら数秒後PCが落ちた XPとかWindows7とかじゃないぜ、Windows11の最新が突如電源が切れたんだよプツンて まじでビビった ちなみに原因は日本語フォントを読み込むコードをカメラキャプチャのループ内(数十から数百ミリ秒ぐらい?)で実行していた C言語のポインタは危険とか言うけどさ、一番危険なのは俺みたいな馬鹿なコード書く奴の存在だよ
考えようによっては、タチの悪いDoSじゃないかw カメラごときで全体落としてんじゃねえよ > カーネル層 ロジックバグなんだろうけど、こういうのはしかし難しいね
ドライバーに致命的不具合があったとしても ブルスクになる程度で 電源断まで行くと言うのは考え難い
ドライバの秘孔を突いてカメラに搭載のチップが電源ライン直結になったとかじゃね?
原因はそっち(ドライバ)ではなくスリープなしのループ内でフォントファイルに連続攻撃したことだぜ、たぶん 簡単に書くとこんな感じ fontpath ='C:\\Windows\\Fonts\\DFJGOTEB.TTC' while True: put_ja(point, text) def put_ja(point, text): font = ImageFont.truetype(fontpath, 32) draw.text(point, text, fill=color, font=font) 実際にはwhileじゃなくてafterでループさせてたけど 日本語出力の時、出力のたびにフォントファイル読み込んでたようで結果PCが落ちた 残像攻撃を受けた感じだったのかもしれん、コロ先生の分身みたいなやつ
プリエンプティブカーネル使っててスリープなしのループごときでそんなことあり得るのか? 逆にそうなった仕組みが知りたい。
インテルのTurboBoostだかで負荷もブーストされて排熱が間に合わずMBにダメージ与えつつ逝ったんじゃないの PC買い換えた方がいいよ
スレチで申し訳ないが、
俺も気にはなってるけどPC痛めつけてまでやる気にはなれない
試したいなら試してくれ、ただしどうなっても責任は負わんぞw
MicrosoftストアのPython Software Foundationってとこの奴
Python 3.13.1 (tags/v3.13.1:0671451, Dec 3 2024, 19:06:28) [MSC v.1942 64 bit (AMD64)] on win32
OpenCVで日本語表示
https://monomonotech.jp/kurage/raspberrypi/opencv_japanese.html ここのputText_japaneseを参考にした(パスとかwindows用に書き換え)
んで、それを
【簡単】QRコードの作成と読み取り in Python
https://qiita.com/PoodleMaster/items/0afbce4be7e442e75be6 のcv2.putTextと置き換えるように書き換えたんよ
引数のfontはなくしてフォントサイズだけを渡す
ImageFont.truetypeがフォントサイズも引数にしているから、こうすれば動的なフォントサイズ変更にも対応できるな、ヨシ!って思ってね
それ実行したらPC落ちた
それでも数回やって問題なかった記憶はあるんだけどね(ただし数十秒程度の起動時間だった)
ちょっと長めに起動させたままにしたからリソース食いつぶしたのかな?と思ってる
lud20250202143045このスレへの固定リンク: http://5chb.net/r/tech/1721137434/ ヒント: 5chスレのurlに http ://xxxx.5chb .net/xxxx のようにb を入れるだけでここでスレ保存、閲覧できます。 TOPへ TOPへ
全掲示板一覧 この掲示板へ 人気スレ |
Youtube 動画
>50
>100
>200
>300
>500
>1000枚
新着画像 ↓「C言語なら俺に聞け 163 YouTube動画>1本 ->画像>2枚 」 を見た人も見ています:・C言語なら俺に聞け 156 ・C言語なら俺に聞け 144 ・C言語なら俺に聞け 147 ・C言語なら俺に聞け 146 ・LinuxカーネルはC言語なのにオブジェクト指向 ・【悲報】C言語なら10秒で終わる処理、Pythonだと11分かかった ・100人に聞いた最初に学んだプログラミング 3位「C言語」、2位「Java」、1位は「Phthon」 ・C言語って… ・c言語的にjavaを教えて ・[システム]プログラム言語など学習スレ[初心者] ・C言語を勉強中の大学1回生だが ・無知の俺にC言語について教えてくれ。 ・C#とか言うなんちゃてC言語wwww ・訪日外国人観光客「えっ、わざわざ土人民族の言語なんか覚える必要ある?土人は土人らしく我々「人間」の言葉に合わせなさいよ」 ・ポルトガル語、ネパール語など多言語で避難呼びかけ 兵庫の放送局の津波ニュース対応に称賛「素晴らしい」 SNSでも映像を配信。 [朝一から閉店までφ★] ・【急募】勇者さん助けて;;C言語です ・プログラミングBASIC言語について。 ・高校生3人がc言語初心者からゲーム作る ・8ビットCPUでC言語?ないないありえないっしょ! 5 ・C言語でテトリス作れる人来て!👾 ・クラシックMacでプログラミング [C言語] [その他] ・最長不倒関数■C言語でmain関数に全コードを入れる ・【教えて】C言語勉強してるんだけど、ポインタがあとわからん ・【】流行り廃りはあるけれど、結局C言語に回帰するんだよね。C言語最強なんだよね ・MS「C言語は脆弱だな。改良してやんよ」→標準化! [無断転載禁止] ・なぜこれまでなかった? C言語の公式ホームページが新たに公開、テキスト中心の簡潔な内容 [朝一から閉店までφ★] ・【SE】「C言語…?どこかで見た程度でOK」 名古屋のアテック、求人広告が話題に エンジニアの人材不足、面白求人でカバーできる?★2 ・【話題】 フランス選手による日本人侮辱問題 言語学者(75) 「ひろゆき(44)は『論破王』ではなく、『論理破綻王』の間違いですね」★3 [ベクトル空間★] ・ひろゆき(44)が言語学者・小島剛一氏(F爺)に反論「論点を逸らそうとひたすら長文をブログに書いてるのはあなたです」「勉強不足」★3 [Anonymous★] ・【八街・児童5人死傷】被害児童の祖母「“視力が無い、味覚も無い、言語もわからない、生きてるだけかもしれない”と医者に言われた…」★3 [potato★] ・言語スレ ・もし言語で ・認知言語学 ・言語自由詩 ・世界の言語差別 ・関東弁は土人の言語 ・プログラム言語 ・人工言語を作りたい ・関東弁はバカの言語 ・愚民の話す言語の翻訳は難しい ・世界で共通する言語は3つ ・人工言語アルカその6 ・認知言語学総合スレ ・糞言語が天下を取る理由 ・プログラム言語を作ろう ・英語って欠陥言語じゃね? ・人造言語を作りたいスレ ・言語って目と関係性あるの? ・アフリカの言語で話すスレ ・多言語間の完全自動翻訳技術 ・人工言語インターリングア ・【悲報】日本語、欠陥言語だった ・関数型言語一般 [無断転載禁止] ・RubyでSQLを作ろう! 最強DSL言語 ・小林製薬の言語センスwwww ・子音が多い人工言語を作ろう ・駅の切り替わる多言語表示やめろ! ・言語学板を復興させる方法は? ・言語学やってる奴ちょっと来てくれ ・おま国おま値おま言語スレ ・言語のギミックを製造したよ ・遊戯王やってる奴スレ多言語版 ・印欧語族と北米先住民の言語の関係性 ・言語学板の顔面・米津玄師について ・関東弁はバカの言語 [無断転載禁止] ・文化進化論言語活音質音楽
07:54:59 up 51 days, 8:53, 1 user, load average: 6.82, 7.13, 7.36
in 1.4662098884583 sec
@1.4662098884583@0b7 on 060720