X



C言語なら俺に聞け 158

■ このスレッドは過去ログ倉庫に格納されています
0001デフォルトの名無しさん (ブーイモ MMcf-4SjH)
垢版 |
2021/12/25(土) 12:11:46.61ID:xxeaCAplM
!extend:checked:vvvvv:1000:512
(新スレ立ての際上記コマンドを2行書き込んでください)
C言語の話題のみ取り扱います C++の話題はC++スレへ
質問には最低限の情報(ソース/コンパイラ/OS)を付ける
数行で収まらないソースは以下を適当に使ってURLを晒す
https://paiza.io/
https://ideone.com/
http://codepad.org/

C17
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/n4713.pdf

C11
http://www.open-std.org/jtc1/sc22/WG14/www/docs/n1570.pdf

C99
http://www.open-std.org/jtc1/sc22/WG14/www/docs/n1256.pdf
http://kikakurui.com/x3/X3010-2003-01.html

C FAQ 日本語訳
http://www.kouno.jp/home/c_faq/

JPCERT C コーディングスタンダード
https://www.jpcert.or.jp/sc-rules/

※前スレ
C言語なら俺に聞け 157
https://mevius.5ch.net/test/read.cgi/tech/1624846971/
VIPQ2_EXTDAT: checked:vvvvv:1000:512:: EXT was configured
0739デフォルトの名無しさん (ワッチョイ ff01-NwEC)
垢版 |
2022/06/15(水) 19:53:29.20ID:XKwaNEU70
>>736
C言語で書いたコードが実行できるようなCPUでCALL相当の命令がない奴なんてあるのか?
まさかと思うけどBSR(Branch SubRoutin)とかBAS(Branch and Save)はCALLと綴りが違うんだーっていう主張じゃないよね
0744デフォルトの名無しさん (ワッチョイ 7f36-GGE9)
垢版 |
2022/06/15(水) 20:29:16.05ID:mSaBC5As0
>739
2000年あたりのスパコンのデバッグやってたけどスタックポインタ自体無かったよ。
汎用レジスタの一つをスタックポインタの様に使ってた。
スパコンのPEはCPUじゃ無いっていうならそれまでだけど。

OSがCで書かれてたよ。
0745はちみつ餃子 ◆8X2XSCHEME (ワッチョイ 6f3e-GGE9)
垢版 |
2022/06/15(水) 20:38:36.75ID:VY0KZJ3n0
専用のレジスタを用意するかわりにアドレシングモードを充実させてるタイプの CPU もあるとは聞いたことは有る。
複数のスタックを用途別に使ったりする運用も出来るので便利っぽいよ。
0747デフォルトの名無しさん (ワッチョイ ff01-NwEC)
垢版 |
2022/06/15(水) 21:27:21.82ID:XKwaNEU70
>>744
だから>>740に書いたように汎用機みたいにハードウェアスタックが無いプロセッサーは普通にあるよ
でもBASみたいにサブルーチンを呼び出す命令はある(戻りアドレスをレジスタに格納してジャンプする)
スパコンの命令セットは見たことないけど似たような命令はあると思う
0751デフォルトの名無しさん (ワッチョイ cfbb-D3sd)
垢版 |
2022/06/15(水) 21:56:54.74ID:Ltc382Vw0
Z8スーパーコンピュータ
0753デフォルトの名無しさん (ワッチョイ 7f36-GGE9)
垢版 |
2022/06/15(水) 22:55:33.80ID:mSaBC5As0
>750
富士通。
実機は見たこと無い。
なんかアメリカに設置されてて、日本の端末(FMVにFreeBSDかなんか入れてた)からtelnetで入って作業してた。
入社1年目だったんでテスト作業員+フリーズした場所の特定と原因予想してた。
0756デフォルトの名無しさん (ワッチョイ 93bb-zkCy)
垢版 |
2022/06/16(木) 14:04:28.10ID:6d6damS40
① struct _Hoge;
② typedef struct _Hoge Hoge;
③ struct _Hoge { int a; };
④ typedef struct _Hoge { int a; } Hoge;

↑の①~④はどれが「定義」でどれが「宣言」かよくわからんです
typedef の def は define(定義)の def ですが
変数作って値を定義していないので全部宣言ですかね?
0760デフォルトの名無しさん (アウアウウー Sa67-iSSN)
垢版 |
2022/06/16(木) 19:53:21.43ID:hEUIHdUOa
コンパイラが単語を覚えるのが宣言
メモリに実態が産まれるのが定義
0763デフォルトの名無しさん (ワッチョイ cf63-GGE9)
垢版 |
2022/06/16(木) 23:14:06.95ID:y5qePP6X0
そういう風に決めたなら仕方がないが
意味的には、定義と宣言って逆な印象を受けます
数学でいうと、
点や直線の定義では実際の描画はまだですが
点や直線の宣言っていうと、その場に描画すると言うイメージ
0764はちみつ餃子 ◆8X2XSCHEME (ワッチョイ 6f3e-GGE9)
垢版 |
2022/06/16(木) 23:16:16.53ID:yR1zGyRS0
宣言と定義の意味については C99 だと 6.7 に記述がある

> 宣言は、幾つかの識別子の解釈及び属性を指定する。
> 識別子の定義 (definition) とは、宣言のうち次のものをいう。
> ・ オブジェクトに対しては、そのオブジェクトの記憶域を確保する宣言
> ・ 関数に対しては、関数本体を含む宣言
> ・ 列挙定数又は型定義名に対しては、その識別子の (唯一の) 宣言

逆に言えば定義は常に宣言でもある。
0765デフォルトの名無しさん (ワッチョイ cfae-/e9c)
垢版 |
2022/06/17(金) 05:27:18.60ID:zopwF6/i0
実体が作られるといっても
プログラムイメージにスペースが確保されるとは限らない
静的記憶域期間を持つものはプログラムイメージに作られるが
自動記憶域期間を持つものは実行中に割付と解放が行われるし
構造体のメンバ宣言並びはコンパイラのメモリに作られる

これらのいずれも「定義」となる
0767デフォルトの名無しさん (ワッチョイ 0310-GGE9)
垢版 |
2022/06/17(金) 08:44:28.03ID:rAke7YJm0
なんとなくのイメージ
・宣言
「xxxxって名前の変数(関数)がどっかにあるらしいよ。詳しいことは知らん。」

・定義
「xxxxの詳細はココに書かれたxxxxxである!これは決定事項である!!」
0768デフォルトの名無しさん (ワッチョイ cfae-/e9c)
垢版 |
2022/06/17(金) 13:54:11.29ID:zopwF6/i0
>>766
struct _Hoge;
struct _Hoge; // OK
これは _Hoge という識別子がタグ名という定型データとして作られ、
その後、定型データの中の属性フラグが検査されて一致が確認される

struct _Hoge;
union _Hoge; // NG
これは定型データの中の属性フラグが検査され不一致が検出される

struct _Hoge;
struct _Hoge { int a; }; // OK
これは定型データの中のポインタがまずNULLで作られ、
次に、そのポインタでメンバ宣言列という不定型データを指す

struct _Hoge { int a; };
struct _Hoge { int a; }; // NG
これは既にNULLでなくなったポインタの貼りかえで拒否される

宣言の重複は矛盾の検出のみを行い
定義の重複は不定型データの再作成で拒否される
{ } は無結合
0769デフォルトの名無しさん (アウアウウー Sa67-iSSN)
垢版 |
2022/06/17(金) 16:09:04.52ID:G79h5Zera
>>763
誤訳
0770デフォルトの名無しさん (アウアウウー Sa67-iSSN)
垢版 |
2022/06/17(金) 16:13:44.68ID:G79h5Zera
struct _Hoge { int a; };
struct _Hoge { int a; }; // NG

この場合でもコンパイル単位が別ファイルだと(ほぼ)問題無い訳で
一致していなければ一致していないなりの結果が産まれる
0773デフォルトの名無しさん (アウアウウー Sa47-vQ73)
垢版 |
2022/06/18(土) 20:10:05.11ID:cOcEcivya
ヘッダ include したことないとか
ヘッダに実装描くとか
分割コンパイルしたことないとか
そういうアホのにおいがプンプン丸
0774デフォルトの名無しさん (ワッチョイ ffad-P2F3)
垢版 |
2022/06/18(土) 23:11:41.82ID:eg6b2Ems0
どこにそんな話出てた…?
0777デフォルトの名無しさん (オッペケ Sr3b-P2F3)
垢版 |
2022/06/20(月) 20:11:30.62ID:8GsqMDfwr
ヘッダに実装書いたっていうレスもヘッダをincludeしたことないっていうレスも見当たらないけど…
0778デフォルトの名無しさん (スップ Sdba-JtvC)
垢版 |
2022/06/20(月) 20:27:07.42ID:aPzFu0cfd
別ソースから同じヘッダをincludeしていてもコンパイル時には必ず別ファイルとなるわけで(ほぼ)じゃ困る
0779デフォルトの名無しさん (ワッチョイ ffad-DcGD)
垢版 |
2022/06/25(土) 17:14:53.88ID:g21tYZQo0
if ( a == 0 )
{ port &= 0b11011111 ;
}
else
{ port |= 0b00100000 ;
}

これ条件文使わずに書けるよね?
0784デフォルトの名無しさん (ワッチョイ ffad-DcGD)
垢版 |
2022/06/25(土) 18:15:30.63ID:g21tYZQo0
おまいらは何で素直にかけないんだ?(´・ω・`)?
0785デフォルトの名無しさん (オッペケ Sra3-Htnq)
垢版 |
2022/06/25(土) 18:26:40.73ID:XIyeaAEpr
>>779
条件分を使わない理由はないよね?
0787デフォルトの名無しさん (ワッチョイ 3f32-iCO3)
垢版 |
2022/06/25(土) 18:28:36.26ID:gQjoPRQF0
条件によって8ビット目以上も変える訳ではないのならば…かな
&= 0b11011111 | !!a << 5や&= ~0b00100000 | !!a << 5とかも論理否定は楽な方で
後者は若干レジスタ雑に出来るが…しかし最適化するとif文も分岐排除されてほぼ変わらん
0815デフォルトの名無しさん (ワッチョイ 8302-Fj9x)
垢版 |
2022/07/11(月) 08:40:13.85ID:2XjvtJRn0
voidの長さはよくわからんが、取り敢えずvoid*のインクリ幅を実装の最小単位に取っておけば何でも指せるし、そのアドレス演算に意味を持たせる事も可能になる
どうしてもvoidのサイズを決めたいというのなら、まあ合理的な実装だと思う
0820はちみつ餃子 ◆8X2XSCHEME (ワッチョイ 1b3e-TkQT)
垢版 |
2022/07/11(月) 17:46:10.96ID:POJvWuxZ0
そう。
オブジェクトを指すポインタは void* との間で「暗黙に」変換することが出来る。
最終的に char* にキャストするのだとしてもインターフェイス (仮引数) が void* だとキャストをせずに済む。
memmove とかがそれ。
0821デフォルトの名無しさん (スッップ Sd43-sZie)
垢版 |
2022/07/11(月) 22:57:06.26ID:7aXqGp3Qd
なんでも指せるのとインクリメント幅を1にするのは関係ない
むしろインクリメントしようとしたらミスである可能性が高いのでワーニングかエラーにすべき
0823はちみつ餃子 ◆8X2XSCHEME (ワッチョイ 1b3e-TkQT)
垢版 |
2022/07/12(火) 10:12:07.41ID:AnYAkaOT0
C の仕様上はアドレスを定義できる単位をバイトと呼び、 char は 1 バイトであると定義されてる。
つまり char はハードウェア的な最小単位と言えるが……、まあ名前が良くないのは確か。
0826デフォルトの名無しさん (ワッチョイ 23ad-dHWA)
垢版 |
2022/07/12(火) 17:42:00.57ID:4CshQ+Jw0
というかなんでcharってsignedにしてあるんだろ?
char と unsigned charじゃなくてchar と signed char にしてくれていればよかったのにと思わなくもない
intもsignedだし(逆にintがunsignedだったら使いづらいけど)符号付の計算が基本とかあるのかね?
0827デフォルトの名無しさん (ワッチョイ a5d2-WFmy)
垢版 |
2022/07/12(火) 17:58:33.14ID:YvrX4qJi0
C++ではcharが符号付きか符号なしかは環境依存だよ
unsigned charともsigned charとも別の型扱いされる不思議な子

たぶんC言語でも同じ扱いだろう
0829はちみつ餃子 ◆8X2XSCHEME (ワッチョイ 1b3e-TkQT)
垢版 |
2022/07/12(火) 18:30:46.85ID:AnYAkaOT0
そう。 >>827 の説明が正しい。
char の符号は処理系定義かつ signed char とも unsigned char とも異なる独立した型。
signed char か unsigned char のどちらかと別名という可能性もないので、
C++ のオーバーロードや C の _Generic で三種類に分岐することは出来るよ。

char は整数だから他の整数型との一貫性で考えれば符号付きになるのが自然なようにも思えるが……、
実行基本文字集合は char で (char が符号有りだとしても) 正の値になることを
要求している (C99 だと 6.2.5 に書いてある) ので各環境が採用している文字コードによっては
符号無しにせざるを得なかったのだと思う。
EBCDIC とかだとどうしてもそうなる。

まあ負の文字コードが有っても辻褄合わせは出来たとは思うんだが、
仕様が成立した時点でそうでない想定をしているコードが結構あったりしたんじゃないかな。
0831デフォルトの名無しさん (ワッチョイ ad69-jszV)
垢版 |
2022/07/13(水) 11:20:33.14ID:Zw91A11j0
>>829
>まあ負の文字コードが有っても辻褄合わせは出来たとは思うんだが、
比較の際に暗黙で走る int への格上げの時にややこしくなりそうやね

char ch;
...
if (ch >= 0x80) // 上位ビット立ってる?
0833デフォルトの名無しさん (ラクッペペ MMcb-KYPL)
垢版 |
2022/07/13(水) 12:43:05.67ID:hH7ZnQ+pM
&buf[0] 配列の先頭要素のアドレス
buf 配列の先頭のアドレス
同じ

sizeof(&buf[0]) 配列の先頭要素のサイズ
sizeof(buf) 配列のサイズ
異なる

配列の要素数を求める場合
sizeof(buf)/sizeof(&buf[0])
で頻出する
0836はちみつ餃子 ◆8X2XSCHEME (ワッチョイ a33e-TkQT)
垢版 |
2022/07/13(水) 14:23:32.52ID:Kb1eM8RI0
>>832
配列の先頭としての意味よりその要素に意味があるということを強調した雰囲気を表すためにそういう書き方をすることはあるよ。
仕様としての解釈 (動作) に差が無い場面であっても人が読む上では雰囲気の差はある。
■ このスレッドは過去ログ倉庫に格納されています

ニューススポーツなんでも実況