C言語なら俺に聞け 161

■ このスレッドは過去ログ倉庫に格納されています
2023/04/21(金) 14:05:20.18ID:rqj2HSDF0
!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

C23 最新ドラフト
https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3047.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言語なら俺に聞け 160
https://mevius.5ch.net/test/read.cgi/tech/1672191630/
VIPQ2_EXTDAT: checked:vvvvv:1000:512:: EXT was configured
2023/09/01(金) 01:19:09.35ID:APE9whcz0
>>565
適合する型なら許される、という点は理解しています。
しかし「void* と FILE* は適合しない」のであれば、
>>563 の例も不適合ではないでしょうか?
また、不適合であっても void* と char* の組み合わせ
の場合なら許される理由は何でしょう?
2023/09/01(金) 01:43:08.25ID:gaibfzWk0
>>566
総合的に言って不適合という理解で正しいということになる。

void* と char* は適合の規則からすると適合ではないのだけれど、
その表現や境界調整は等しいことを保証する規則があるので
この場合に適合と同等の扱いをしても問題にならないから、
まあ出来るようにしておけば便利なこともあるんとちゃうんかなぁ。
2023/09/01(金) 02:40:24.68ID:EYRyaWRCM
>>565
ポインターに0の代入は問題ないけど、ここでの話は可変個引数に渡した時の事を言ってるので((void*)0)じゃないと不味いでしょ
2023/09/01(金) 02:50:24.64ID:EYRyaWRCM
>>565
6.7.5.1では、FILEとvoidが適合しないといけない旨の記述があるけど、voidというのは普通に比較して適合かどうか判定できる型なのか?
特別なルールが有って然るべきな気がするけどね
2023/09/01(金) 09:38:35.84ID:gaibfzWk0
>>568
不味いけど NULL が 0 のことはあるという話。
2023/09/01(金) 18:08:19.15ID:gaibfzWk0
何の話をしてたんだかよくわからんようになったので >>551 を読み返してたんだが
規定が設けられた理由が根本的な疑問ということでいいんかな。

当然だが引数を受け取る側の想定と異なるものを渡したら破綻する。
普通の関数ならコンパイル時に受け取る側と渡す側の型の間に不整合が合ったら
コンパイル時に検出できるし、条件に合えば暗黙の変換もするんだけど
可変長引数の場合は実行時にならないとわからないので
調整する必要なく渡せる条件を規定したらそうなったって感じだと思う。

整数は負数が絡まなければ同じ表現だし
void* と char* にも互換性があることも保証されているので
問題にならない。
2023/09/01(金) 19:53:17.39ID:El2JpNjt0
ポインタ苦いか塩つぱいか
そが上に熱き涙をしたたらせて
コードを書くはいづこの里のならひぞや

「まずい」や「拙い」でなく「不味い」と書かれると、つい...
573デフォルトの名無しさん (アウアウウー Sa11-sVGh)
垢版 |
2023/09/01(金) 20:42:45.29ID:5C0TsKNSa
メモリの先頭をいじっている時点で頭がおかしいが
574デフォルトの名無しさん (アウアウウー Sa11-sVGh)
垢版 |
2023/09/01(金) 21:08:05.68ID:5C0TsKNSa
ヌル文字の実体が数値のゼロということから思いついた理屈なのかな?

ポインタはアドレスで、そのアドレスに格納されている値のことではない。
2023/09/01(金) 21:13:54.66ID:APE9whcz0
>>571
色々ありがとうございました。

素朴に考えて、呼び元がポインタを渡し、
それを呼び先がポインタとして受け取れば
(それが何型へのポインタであろうとも)
普通に安全そうに見えるのに、何でこんなに厳しいのか?
そう決まった理由が知りたかった為の質問でした。

誰か、そこら辺の事情を知っている人はいないか? と。
576デフォルトの名無しさん (ワッチョイ d95f-sVGh)
垢版 |
2023/09/01(金) 21:37:10.15ID:qVeR1pY40
>>575
C言語のポインタは単にアドレス

ただし、構造体なら構造体、関数なら関数で、メモリ上に決まった配置をされるので、なんのポインタかわからないと、メモリのアドレスをずっと追いかけることになる。

コンピューターそのものにはデータ型というものは存在しない。
2023/09/01(金) 22:14:19.34ID:LLAg+6GRd
>>575
単純にアラインの問題じゃないの
char型なら1バイト単位だからどんなアドレスでもOKだが
それ以上のサイズの変数へのポインタは他のポインタへ変換できない可能性があるというのがたてまえで
2023/09/01(金) 23:22:02.51ID:gaibfzWk0
>>575
ポインタの表現は、それが指す先の型によって異なることも言語仕様としては許されるはず。
§6.2.5 でポインタの表現や境界調整要求が等しくあるべき条件が規定されていて
それ以外の条件では同じ表現または境界調整要求を持つ必要はないと書かれてる。

まあそんなアーキテクチャがどれくらい存在するのかは知らんけど
2023/09/02(土) 00:36:03.53ID:WsIZ4FVlM
いやいや、ポインター(アドレス)自体はアライメントされてない所に格納されてるかもしれんけど、中身のアドレス自体は問題ないアライメントになってることが保証されてるでしょ
オマエらは何を言ってるんだ?
580デフォルトの名無しさん (ワッチョイ ffad-5+Xn)
垢版 |
2023/09/02(土) 00:41:32.42ID:VX6uRHRw0
farポインタみたいにバイト数の違うポインタも混在していたら余計にややこしい問題に・・・
2023/09/02(土) 01:01:48.59ID:WsIZ4FVlM
例えばFILE*とshort*ならアドレスのアライメントが合わない場合があるだろうけど、これはそもそも型が適合しないわけでどうしようもない
でも、今考えたらvoid*はありとあらゆるアドレスを取る可能性が有るから、それに合うのはchar*しかないよ、ということを言いたかったのだろうなと気付いた
でも規格書を見ても、FILE*とvoid*が適合するかどうかはアンドキュメンテッドだなw
現実には((void*)0)とFILE*は完全に適合してるけどね
2023/09/02(土) 06:58:16.01ID:XjF1xIbI0
ここにこう書いてあるからには、何か(通常の関数呼び出しでは
問題にならないが)可変長引数特有の問題があり、
それを避けるためにこうしたのだろう、と思った訳です。
2023/09/02(土) 11:49:29.07ID:+azsBNOBd
>>579
そんな保証はまったくない
例えばmallocの場合戻り値は「あらゆる組み込み型に対応できるようにアラインメントされる」と特に注釈されている
逆に言えばvoid*はどんなポインタにキャストしても安全と思い込みがちだがそんなことはないということ

>>582
通常の呼び出しなら型チェックが働くが可変長呼び出しでは一切働かないという注意だろう
最近のprintfは型チェックされるようになってるけど
2023/09/02(土) 11:59:23.66ID:R1w1jy3B0
安全かどうかは、環境によるんじゃ
2023/09/02(土) 12:34:31.87ID:DeBIPPsBd
「環境による」のは安全ではないんだよ
ここで取り上げられてるのは大元の公式文書なのであらゆる環境について言えることが書いてある
2023/09/02(土) 12:59:05.22ID:R1w1jy3B0
マイナーなCPUのことなんか気にしたことがなかったな
2023/09/02(土) 13:12:11.45ID:Ng1Dtdjk0
>>584
現在の文脈では「言語仕様をそう決めた理由」が主題。

だからその前提として言語仕様が保証している範囲がどこまでかを
理解しておく必要があって、そこで見当違いの主張に反論がされている
という話の流れ。
2023/09/02(土) 14:05:43.49ID:DeBIPPsBd
>>586
「可搬性」という概念はCでは大事
マイナーなCPUのみならず将来的に登場する高性能だが制限が多いCPUでも手直しせずに動かせるということもあるかもしれない
2023/09/02(土) 14:41:25.26ID:Ng1Dtdjk0
必要なら環境依存なことをしやすいのも C の良いところだが
不必要な依存は避けるに越したことはないわな
590デフォルトの名無しさん (アウアウウー Sae7-fXI3)
垢版 |
2023/09/02(土) 14:45:40.34ID:mCX3wjBNa
FILE *fp = fopen(...);
void *hoge = (void *)fp;
FILE *fuga = (FILE *)hoge;
みたいなことは禁止されてる?
2023/09/02(土) 14:59:50.63ID:wu0IBgrgd
どうしても必要ならやるしかない
ただfopenの戻り値でFILE構造体の安全性が保証されてるのにわざわざvoid*に代入してからFILE*に戻すのは
正統な金なのに闇銀行に預けて再びマネーロンダリングするような変な手間だ
2023/09/02(土) 15:08:48.05ID:68c+QhTKM
void *型って参照する先の変数のサイズが不明なので右辺値になるのは不可能な気がするけどな
キャストは無理でしょ
2023/09/02(土) 15:12:41.39ID:Ng1Dtdjk0
>>590
オブジェクトを指す (つまり関数ポインタではない) ポインタを
void* に変換してから元の型に変換すると
元のオブジェクトと等しいことは保証されている。
594デフォルトの名無しさん (アウアウウー Sae7-fXI3)
垢版 |
2023/09/02(土) 15:26:23.14ID:mCX3wjBNa
>>592
void じゃなくてもいいや
FILE *fp = fopen(...);
char *hoge = (char *)fp;
FILE *fuga = (FILE *)hoge;
みたいなことは禁止されてる?
2023/09/02(土) 15:40:22.87ID:iw53wgLpd
>>592
なんで?
ポインタはメモリ上の一点を指すもので
インクリメントデクリメントが不可能なだけで
キャストは可能

>>594
いったい何が聞きたいんだ?
禁止はされてないよ
ただこれ見たプログラマは皆「バカだなあw」とは言うだろうw
2023/09/02(土) 15:52:38.82ID:f6/YEIJg0
言葉をちゃんと使うとプログラマ意思疎通がよくなるのでは。
「void * が右辺値になるのは無理」って何だよ。ではなく、正常動作はプログラマの責任になる、って言いたかったんじゃないの?


>>590 みたいなコードは、これだけなら疑問に思うだろうが、こういうコードが有効になる事はあるよ。その一例は

「ここで言うFILE* みたいなモノが複数種類あり」
送信側 - 中継機能 - 受信側
のプログラム構造で送受信のペアは複数あり、中継機能には 実際の中身が何なのかは意識させたくない。

----
ポインタの話から外れて恐縮だが、
例としてタグ・レングス・バリュー形式ってのがあって、「中継者は送受信データがTLV形式の連続であることだけは知っていて」「TとLのサイズは一定」「タグの種類が何種類あるかなんて知らなくていい」
----

これにさらにポインタを含むデータ構造を通信可能にするには?って話で、ポインタ型をバッファ内インデックス値に変換して、ポインタが指す中身も通信データに含める、とか、
サブ構造がポインタ持ってたら再帰的に処理する、とか話は続くが
それはいいとして

>>590 みたいなコードは、現実にはあるよ。という話
2023/09/02(土) 16:04:16.63ID:Ng1Dtdjk0
>>594
オブジェクトを指すポインタは char* (またはその他の文字型をさすポインタ) へ変換することは許されるし文字配列として読んでもよい。 (読んだ結果としてどういうレイアウトになってるかはわからんけど。)

そしてもとの型に型変換したら変換前と等しいことも保証される。
2023/09/02(土) 16:06:19.94ID:Yxb8XUhFd
たしかに言い方が悪かったので

>>592
ポインタは元々サイズは無いもので
対象オブジェクトの先頭アドレスの一点だけを指してるから
void*を含むどんなポインタもキャストすれば力づくで代入できる
ただvoid*にはサイズがないのでinc dec(加減演算)をしようとするとエラーになる

>>594
どんなキャストも禁止されてはいないが
プログラマの責任によって成される最後の手段だと思ったほうがいい
見つかりにくいバグの原因になるので
ソースにコメントで理由を明示しておいたほうがいい
2023/09/02(土) 16:12:48.48ID:f6/YEIJg0
うーん
まだまだ添削できる余地があるぞ…

ここはまあ無料掲示板だが、仕事では、自分には誤解をされやすい性質がある、と意識しなされ
2023/09/02(土) 16:50:14.84ID:JxIOKPq6d
アハハ
なんだこの人w
2023/09/02(土) 17:10:38.18ID:R1w1jy3B0
ここでお金稼ぎしている人いたっけなw
2023/09/02(土) 21:43:01.25ID:5XlbVKpsM
もりたぼ稼ごうとした人はいた
603デフォルトの名無しさん (ワッチョイ b35f-RK05)
垢版 |
2023/09/02(土) 22:10:43.72ID:9Zs5bzSj0
ポインタの宣言は、ポインタの型じゃなくて、ポインタが指しているアドレスの格納値をどう扱うつもりなのかを明示している。

void型のポインタは、ポインタだから、何型のポインタだから、64ビットだったり、32ビットだったりするものではない。
2023/09/03(日) 13:47:13.05ID:ApaaLf4l0
>>603
同じでなければならないという規定はない。
実際に異なる実装が存在するのかどうかは知らんけど。
605デフォルトの名無しさん (スププ Sd1f-ETx6)
垢版 |
2023/09/04(月) 07:48:03.87ID:63U36j7Od
>>594
void void * 登場前の C は
FILE *fp = fopen(...);
int *hoge = (int *)fp;
FILE *fuga = (FILE *)hoge;
だったんじゃないかな
2023/09/04(月) 07:53:14.39ID:YGQMN8Uj0
設計当時はアセンブラの代替言語。
2023/09/04(月) 09:48:09.59ID:R5PUsxPld
>>605

基本はcharだからchar *hoge = (char *)fp;じゃない
なんならint hoge = (int )fp;でもよかった
ほとんどの場合intとポインタのサイズが同じだった
608デフォルトの名無しさん (アウアウウー Sae7-fXI3)
垢版 |
2023/09/04(月) 10:04:32.23ID:/ASAZOX6a
>>607 みたいなのがいるから void が出来たんだよ
2023/09/04(月) 11:07:54.13ID:gab4BDOud
因果逆転だな
2023/09/04(月) 11:19:05.30ID:Ww8QJvvD0
>>607
ウソはだめだ。
俺が見逃しても、はちみつ先生に定規でケツはたかれるぞ
2023/09/04(月) 11:24:33.03ID:Ww8QJvvD0
そういえば、むかーしの情報処理試験には言語選択でマシン語ってのがあって、1メモリアドレス値が指すメモリは 8bit 幅ではなく、 16bit だったように記憶してる。
「特殊な環境を想定しやがって…」と思ったナカマいない?
2023/09/04(月) 11:27:19.73ID:YGQMN8Uj0
試験用アセンブラはCASLだったっけ?
仮想環境で実在しない環境用言語だって。
2023/09/04(月) 12:00:00.02ID:p8KSFCIf0
>>610
char* はどのポインタからも変換できるし
元の型に変換すれば元のポインタと等しいことは保証される。
好ましいとは言えないが変換自体は問題ない。
void* 登場前には (void* 的なことが必要なら) char* が使われていたのは本当だ。

ポインタから整数へも型変換できることは明記されてる。
その結果は処理系定義だが、出来る環境でやるのが悪いわけじゃない。

char* やら int やらで扱ってたら間違った取り扱いをしやすいので
可能なら避けたほうがよくは有るが、 >>607 が言及した範囲には
明瞭に間違いと言えるものは見つけられない。
2023/09/04(月) 12:00:22.47ID:5denWoTkM
メモリが8bitって何も出来ないぞw
2023/09/04(月) 12:05:38.98ID:QM+pFggQM
アドレス範囲ではなくてデータ長が16ビットだったと思う
2023/09/04(月) 12:09:35.09ID:p8KSFCIf0
>>611
C の仕様上の用語では「バイト」が 8bit とは限らない定義になっている。
C の仕様で想定する必要がある程度にはそういう環境もあったのだろうし、
主流ではないにしても特殊というほどの感じでもなかったんちゃうか?

まあ「昔」をいつ頃に想定するかにもよるだろうけど。
2023/09/04(月) 12:24:06.96ID:p8KSFCIf0
>>612
たぶんだけど >>611 が言うのは CASL の前身である CAP-X のことじゃないか?
16bit 単位でアドレスが振られる設計だったはず。
2023/09/04(月) 14:04:31.55ID:F3cE7vUV0
7bitでアルファベットは表せてたしねぇ
文字集合で完結させてた RFC822
2023/09/04(月) 20:56:26.82ID:MxCwE5tq0
実際に1バイトが8ビットじゃないマシンで仕事してた人いる?
経験談を聞いてみたい
つらそう
2023/09/04(月) 21:41:24.34ID:TqSqVDXY0
何がつらいの?
2023/09/04(月) 22:35:30.73ID:yuyUlcPSd
UNIXとか基本9ビットが見え隠れしてる気がする
ファイルのパーミッション---rwxrwxとか
C数値のデフォルトが8進数とか(9ビットなら8進数3ケタでまとまりがいい)
2023/09/04(月) 22:55:40.14ID:ljnGjc/80
あれは9ビットだったのか
2023/09/04(月) 23:38:31.34ID:5denWoTkM
1バイト9bitとか完全に都市伝説だろ…
1ワード(レジスタ)が36bitとかはLispマシーンで使われたりしてたけどね
2023/09/06(水) 06:22:01.74ID:r3vK0XzD0
char が16bitの環境なら使ったことがある
2023/09/06(水) 07:02:16.45ID:Mh27mgbM0
そういうのってどんなCPUなの?
626デフォルトの名無しさん (ワッチョイ cfcf-ATpV)
垢版 |
2023/09/06(水) 09:37:16.14ID:EGh1VJfR0
とりあえずDSPなんかはそうでしょ
ワードマシンって言っちゃっていいか知らんけど、演算の速度をあげるためにワード幅を一番使いそうなビット数にして全部ワード単位でアクセスする設計にしてる
マニュアルにアドレス、char幅、int幅全部同じ何々ビットです注意してねみたいなのがご丁寧に書いてあったりするよ
627デフォルトの名無しさん (スフッ Sd1f-ETx6)
垢版 |
2023/09/06(水) 11:10:12.82ID:QkmiSIQgd
>>622
12bit以上必要だったはず
2023/09/06(水) 11:35:53.69ID:HQrnJbDO0
>>626
勉強になります
DSP触った事ないや
2023/09/06(水) 12:07:23.88ID:TIQAYIu40
>>626
float 幅に全揃え
アドレッシングもその単位なのでどうしても細かい粒度で個別に演算処理したい時はビットシフト併用
とかあったなぁ
2023/09/06(水) 15:01:09.34ID:7li0jtwXM
よく分からんけどDSPの内部レジスタって直接浮動少数点数が扱えるのか
floatは符号1bit + 指数部8bit +仮数部23bitの32bit長だっけ?
ただ浮動少数点数でビットシフトって面倒くさそう
2023/09/06(水) 19:43:08.02ID:r3vK0XzD0
外部とやり取りが多少面倒
ファイルや通信関連

データ列をcharに8bitずつ入れるか
ケチって8bit x2 入れるか
なんかを考える必要がある
2023/09/06(水) 19:43:50.40ID:r3vK0XzD0
私が使ったのはDSPでした
2023/09/06(水) 19:45:03.72ID:r3vK0XzD0
昔の大型計算機でcharが64bitのがあったはず
2023/09/06(水) 20:55:53.98ID:6iN9QRCz0
最初のUNIX開発マシン、DECの PDP-7 は18ビットだった
2023/09/07(木) 00:34:19.14ID:n7kUX99P0
C の仕様では正数型の表現にパディングビットの存在を許しているんだけど値の表現に関わらない無意味なビット(特殊なフラグとかに使うのか?)が存在するアーキテクチャも、見たことはないけど C の仕様で想定している以上はたぶんあるんだろうな……
2023/09/07(木) 00:34:47.43ID:n7kUX99P0
誤植
正数→整数
2023/09/07(木) 08:06:18.17ID:YzioMxaL0
>>635
小数なら身近にあるね
2023/09/07(木) 12:49:26.03ID:6eZunc+30
隣で寝ている
639デフォルトの名無しさん (ワッチョイ 0f01-e7Rb)
垢版 |
2023/09/16(土) 10:51:51.48ID:S5cqLcA00
T,o,k(迷惑という方は←をあぼーんしてください。)

更に家族友人にも教えて加えて¥4000×人数をGETできます
https://i.imgur.com/dGH5X8i.jpg
640デフォルトの名無しさん (アウアウウー Sa53-HRje)
垢版 |
2023/09/16(土) 12:25:15.03ID:RATZO/gia
しね
2023/09/16(土) 12:35:05.81ID:n1ZKqkE80
>>639
PayPayに変換できるって知らなかった
2023/09/16(土) 12:38:47.03ID:NMUMDiAt0
あそこはEUから莫大な賠償金請求されたから、必死なんだろう
643デフォルトの名無しさん (ワッチョイ 3fad-xbk3)
垢版 |
2023/09/16(土) 12:48:52.21ID:8u+hT5wA0
>>639
グロ
644デフォルトの名無しさん (ワッチョイ 4fb0-gBtz)
垢版 |
2023/09/22(金) 10:15:48.77ID:wJrbx3oK0
なあ、いつから子関数内で宣言した自動変数を戻り値に使って親関数で参照してもアクセスエラーにならなくなったんだ?
特に構造体とか
2023/09/22(金) 10:51:22.61ID:tfij4Zir0
自動変数を参照渡ししてるのか?
2023/09/22(金) 11:07:25.29ID:8SLDLfd50
アクセスエラーってのが実行時の話なら動作環境教えてくれないとなんとも
2023/09/22(金) 11:08:43.04ID:X0VLPMl/0
すんません何を言ってるのか分からん
自動変数のアドレスを返す話?
OSとかコンパイラとか色々わからないと空虚な話になりそう、ってのと(特殊な環境なのでは)

エラーになって欲しいのにならなくて
同僚がアホで困ってて
強制的にエラーにしたいって話?
2023/09/22(金) 11:13:15.28ID:z1xJQo5k0
数年に1回ほぼVC++でほぼCのコード書いてコンパイルしてるけど、
なんか最新版入れる度にデフォのエラー基準厳しくなっていく・・・。

変数定義をgoto(エラー処理)ですっ飛ばからエラーって・・・昔のCみたいに関数先頭に記述を移動する羽目に・・・
警告でいいやん。
2023/09/22(金) 11:16:56.77ID:tfij4Zir0
構造体で返すにしても、呼出元って用意した変数なり構造体で受け取るんだろう
650デフォルトの名無しさん (ワッチョイ 3fad-d4nU)
垢版 |
2023/09/22(金) 11:27:24.08ID:ZXfr4S/70
>>644
構造体の変数を戻り値に使うことは結構最初の頃から出来たと思うが、昔のマイコンは遅かったのでなるべく使わないで呼ぶ側で変数作ってそのポインタ渡してそこに値入れてもらうみたいな事してたよ。

なんで遅いのかっていうと、参照などという高度なワザは使ってなくて他のintとかの変数と同様に構造体の内容をコピーしているだけだからだ。
2023/09/22(金) 11:28:55.72ID:tfij4Zir0
共用体で渡したときは、どのメンバー使ってコピーするの?
652デフォルトの名無しさん (アウアウウー Sa53-9C00)
垢版 |
2023/09/22(金) 12:01:20.53ID:dkRHHNCea
池沼か
653デフォルトの名無しさん (ワッチョイ 4fb0-gBtz)
垢版 |
2023/09/22(金) 12:15:37.49ID:wJrbx3oK0
>>650
処理系によってはポインター渡しになってたはず
自動変数はスタック上に領域確保するので
実体渡しじゃ無いとスタック壊れてるよね?
2023/09/22(金) 12:21:54.90ID:+zFc5v5MM
初期K&Rじゃ構造体returnはなくてポータブルC以降じゃね?
2023/09/22(金) 14:01:49.98ID:jd4xXbI20
構造体を返却値にするときは、
一般的なパソコンでの呼出し規約 (Windows や System V ABI) では
呼出し側で領域を用意してそのアドレスを暗黙の引数として渡す仕組みになってる。

用意された領域の上に最初から値を直接に構築できることもあるので
そういうときはコピーコストは発生しない。
単純な関数、かつモダンなコンパイラを使ってるときは余計な工夫をする必要はないよ。
656デフォルトの名無しさん (ワッチョイ 4fb0-gBtz)
垢版 |
2023/09/22(金) 14:35:59.04ID:wJrbx3oK0
戻り値に構造体を使いたいんですぅ
2023/09/22(金) 14:53:23.56ID:HzXlnxdE0
参照てか自動変数へのポインタを戻してたってこと?

struct foo * hoge()
{
  struct foo body;
  retrun &body;
}

これ未定義だからどうとでもなってしまうんじゃなかったかな…
コンパイラが気を利かしてエラーや警告にするのも
そのまま実行コードを生成して想定外の動きをするのも
658デフォルトの名無しさん (アウアウウー Sa53-9C00)
垢版 |
2023/09/22(金) 15:05:47.80ID:dkRHHNCea
>>656
これでいいだろ
struct Hoge *fuga(struct Hoge *param0, int param1, char *param2){
何かする
return param0;
}
659デフォルトの名無しさん (ワッチョイ 4fb0-gBtz)
垢版 |
2023/09/22(金) 15:07:59.94ID:wJrbx3oK0
受ける側が用意しなあかんかぁ
2023/09/22(金) 15:08:23.02ID:HzXlnxdE0
>>657 のは、OS側のメモリに対する不正アクセスに引っかかって
エラー発報になるのは少ないんじゃないかな?
(戻りの自動変数のポインタが不正アクセスになる可能性は低い)

構造体の中にさらにポインタをつかってて、ゴミなポインタ値で実体見に行ってやっと上記が発動する

struct foo {
 struct foo* next;
  int body;
};
こんなので ret->next->body; とやったら *ret の内容がゴミ = ret->next も不定な値
ret->next->body でメモリの不正アクセス
661デフォルトの名無しさん (ワッチョイ 4fb0-gBtz)
垢版 |
2023/09/22(金) 15:09:39.40ID:wJrbx3oK0
割り込み処理があると簡単に死ぬよ
2023/09/22(金) 15:10:08.95ID:HzXlnxdE0
ハイコストなのをわかってて実体をそのまま返すことはあった
複素数を取り扱う Complex 構造体で 式の形式にしたくて ね
2023/09/22(金) 15:11:28.51ID:HzXlnxdE0
>>661
割り込み想定するなら呼び出し元で器渡しとけって話にしかならんじゃろ
2023/09/22(金) 15:14:27.76ID:wMC0ce2ad
>>653
返値用にもスタックが用意されてる
特にサイズが自由に定義できる構造体では戻り値にレジスタは使えんだろう
2023/09/22(金) 15:27:37.08ID:HzXlnxdE0
ID:wJrbx3oK0 がどういう環境で愚痴ってるのかはわからんけど
「割り込みハンドラ内でいろいろやるのをCで記述してるんだけど…」とかだったら
極力スタックは少なくしたい って話に行き着くけども

それならなおさら器は呼び出し側で用意すべし になるよなぁ
最悪関数呼び出しのオーバーヘッドも嫌って きもいマクロ関数が並ぶことも
■ このスレッドは過去ログ倉庫に格納されています
5ちゃんねるの広告が気に入らない場合は、こちらをクリックしてください。

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