23/11/30 15:08:15.57 3QI4e6Tt0.net
配列 a は a と書くだけで先頭要素を指すポインタなので
&a[0] と書くってのは 0 を足すという要らんことをしているという扱いってこと。
146:デフォルトの名無しさん (ワッチョイ 5f79-/KuA)
23/11/30 20:20:41.06 4nwqW1NG0.net
>>140
pがザビ家でaがジオン公国そのものと言ったら判りやすいだろうか
ジオンはザビ家にNTRれたけど元のジオン・ダイクンが掲げた思想(長さとか)はNTRが完了した時点で失われた
その後出てきたアクシズ(ネオ・ジオン)はもっと酷くてジオンと言える部分はNTRしたザビ家の跡取りとその傀儡だけでジオンとは一体何だったのか語れる人物は一人もいない
147:デフォルトの名無しさん (ワッチョイ 47e7-xen6)
23/11/30 20:26:04.69 SvZ2/mZg0.net
>>143
そっちのほうが余計なギミックじゃない?
a[]のアドレスが欲しければ&aと書くだけでいいのに
aが自動的にa[]の先頭番地になってしまうからややこしい
ちなみにBASICだと配列と同名の単純変数が作れてしまいこれも今思うと無茶苦茶だった
148:デフォルトの名無しさん (アウアウウー Sa0b-6V65)
23/11/30 20:46:09.47 h/B+JtY5a.net
>>117
意味無いわ
149:デフォルトの名無しさん (アウアウウー Sa0b-6V65)
23/11/30 20:47:46.07 h/B+JtY5a.net
完全に理解した!!!
↓
URLリンク(ideone.com)
#include <stdio.h>
#define N 3
int main(int argc, char **argv)
{
char *hoge[] = {"abcd", "efg"};
char **hige = hoge;
char hage[][N] = {"ab", "cd", "ef", "gh"};
char (*fuga)[N] = hage;
char (*moga)[N] = {"ab", "cd", "ef", "gh"};
printf("%zd %s %s\n", sizeof(hoge), hoge[0], hoge[1]);
printf("%zd %s %s\n", sizeof(hige), hige[0], hige[1]);
printf("%zd %s %s %s %s\n", sizeof(hage), hage[0], hage[1], hage[2], hage[3]);
printf("%zd %s %s %s %s\n", sizeof(fuga), fuga[0], fuga[1], fuga[2], fuga[3]);
printf("%zd %s %s %s %s\n", sizeof(moga), moga[0], moga[1], moga[2], moga[3]);
return 0;
}
↓
説明してみ
150:デフォルトの名無しさん (アウアウウー Sa0b-6V65)
23/11/30 20:51:51.20 h/B+JtY5a.net
アンカ忘れた
>>140
151:はちみつ餃子 ◆8X2XSCHEME (ワッチョイ 5f3e-zy57)
23/11/30 21:26:27.48 3QI4e6Tt0.net
>>145
あくまでも言語仕様の理屈で言えばこうだという説明なのでその言語仕様が良いかどうかの意見は含んでないよ。
色々とアレな部分も多いってのは文句つけても仕方がないいまさらな話だし。
152:デフォルトの名無しさん
23/11/30 22:06:24.41 wy49Mw9yM.net
いやいや何を言っとんの?
利便性のためにそういう仕様にしてるんだよ
C書いてりゃさすがに分かんだろうよw
153:はちみつ餃子
23/11/30 22:36:56.23 3QI4e6Tt0.net
感覚的にはそんなに不自然には感じないんだけど
仕様の規則が変則的なのも確かなので
つまりは人間の感覚は不合理なものってことだ。
154:デフォルトの名無しさん
23/11/30 22:41:39.63 0Cr+jEwb0.net
>>147
%zd は知らなかったわ。 勉強になった
155:はちみつ餃子
23/12/01 00:42:09.23 U5xjJXbM0.net
sizeof の結果の型は size_t で、
size_t は符号なし整数というだけしか規定されていない処理系定義なんだけど
unsigned int や unsigned long int の別名として定義されていることが多いせいで
それをあてにした形で説明している資料は割とある。
156:デフォルトの名無しさん
23/12/01 02:30:56.67 oKQshtme0.net
>>145
> a[]のアドレスが欲しければ&aと書くだけでいいのに
俺はそっちのほうがややこしいと思うけどな
むしろ*(a+10) を [] で表現するなら *a[10] みたいな書き方になるほうが、理解する上ではややこしくなかったかなとは思うけど(使う上では不便)
[] って箱(マス)に見えるし、まあ直接箱の中身を示すものなのだなって覚えたけど
157:デフォルトの名無しさん
23/12/01 05:52:03.14 sCbOzpGc0.net
誰が誰なのかよく分からんけど、キッズが来て荒れた、という話ですか
インデックスアドレッシングを [ ] 記号に当てただけと思うけど、そんなに難しいかね
158:デフォルトの名無しさん
23/12/01 05:55:20.08 sCbOzpGc0.net
型の話かと思ってたら、いつの間にか 入門者がポインタを理解できない話 になった印象
159:はちみつ餃子 ◆8X2XSCHEME (ワッチョイ 5f3e-d+hN)
23/12/01 14:51:35.53 U5xjJXbM0.net
>>145
配列 a に &a としたときに得られるのは配列を指すポインタであって配列の先頭要素を指すポインタではない。
(型が違う。 アドレスを数値として見たら同じはずだけど。)
多次元配列にアクセスするとき (添字演算子を重ねて適用するとき) に仕様の通りに解釈していくと配列と先頭要素が都合よく切り替わって最終的にポインタ演算になるのが実に上手いこと出来てる。
配列の要素にアクセスするときの記法を現状のような形にするという前提でならなんだかんだでよく出来ている。
配列に & を付けたら配列を指すポインタになるというのは例外的ではない普通の挙動だからそこに別の意味を割り当てるならそれもやっぱり変則的なややこしい挙動ってことになってしまうよ。
160:デフォルトの名無しさん
23/12/01 19:03:26.87 Ga+233FE0.net
>>157
ポインタ完全制覇でよーく理解できました。
20年以上やってきて配列へのポインタは一度だけ出番がありました。
161:はちみつ餃子
23/12/01 19:23:36.92 U5xjJXbM0.net
>>158
プログラマが直接的に書く機会はあんまりないだろうけど、
暗黙には頻繁に表れていてこのルールがないと上手いこと機能しないって話。
#include <stdio.h>
int main(void) {
int foo[2][3] = {
{1, 2, 3},
{4, 5, 6}};
printf("%d\n", foo[1][2]); // ふたつの座標みたいに見えるけど
// 式を各段階に分解すると……
int(*bar)[3] = foo; // 配列を指すポインタは出てきてる!
int *baz = bar[1];
int qux = baz[2];
printf("%d\n", qux);
}
162:デフォルトの名無しさん (ワッチョイ 65d3-WD8q)
23/12/05 07:30:58.43 72+QzLj/0.net
c言語初心者です
質問させてください
FILE *fpという宣言の「FILE」にどういった役割があるのでしょうか
*fpは関数によってどこを読み書きするかを指定するためにアドレスを格納することは分かるのですが
それならばint型のポインタで良いような気もします
プログラムを書く上でどうでもいい内容なのですが教えていただければ今日の寝付きが良くなる気がします
163:デフォルトの名無しさん (ワッチョイ eaad-snvD)
23/12/05 07:53:15.80 kkEdYaZP0.net
>>160
stdio.h の中身を見れば FILE がどう宣言されているか分かるのでは?
164:デフォルトの名無しさん (スフッ Sd0a-Oc+E)
23/12/05 08:16:33.53 64vzQPx0d.net
>>160 FILE構造体っていうことだけは、どの本にも書いてある。
165:デフォルトの名無しさん (ワッチョイ 66d6-8IwF)
23/12/05 08:26:33.63 Sjl8/rh40.net
実際UNIXのfile descriptorはintでWindowsのファイルハンドルHANDLEはvoid*だ。
こいつらはシステムコールによってカーネルモードで操作されるから中身が完全に見えないようになってる
それとは違って標準Cライブラリはユーザモードで動作するから
処理系依存で中身を操作してもいいように作ったのかもしれない
166:デフォルトの名無しさん (スッップ Sd0a-Cw2Y)
23/12/05 08:33:57.88 GHHZLCc/d.net
>>160
確かに構造体の中身を使わないかぎり何のポインタでもいいんだけど
間違えて他のタイプへのポインタと混同した時にエラーが出るから気づきやすい
それはけっこう重要だよ
167:デフォルトの名無しさん (ワッチョイ 65d3-WD8q)
23/12/05 09:00:17.71 72+QzLj/0.net
>>160です
普通の構造体の宣言とは異なり要素の記述はありませんが
「FILE」とは「ファイル構造体を使うよ」と宣言しているという意味で
そうしてstdio.h上のFILE構造体の要素に開いたファイルの情報が代入されていくということでしょうか?
「FILE」を記述せずにfopenで開こうとした場合構造体メンバのptrに代入されている数値が使えないのでfopenから戻り値が受け取れず正しく*fpに座標が代入されない
みたいな
そして開くだけならfopenでも開けてしまうとか
168:はちみつ餃子
23/12/05 10:08:56.47 z5PiblaY0.net
言語仕様的に見れば FILE はストリームを制御するのに十分な情報が入ったオブジェクト型であることと、
アドレス (FILE 型のオブジェクトがある場所) に意味がある場合もあるから
オブジェクトをコピーして機能するとは限らないという程度のことしか書いてない。
FILE にどのような情報が格納されているのかといったことや
詳細な仕組みはホスト環境の事情に合わせて処理系の裁量で決めてよい部分なので、
具体的にどうなっているのかは各実行環境・開発環境ごとに違う。
特に環境依存の細かい部分に立ち入って制御をしたい事情があるのでない限りは
fopen が「なんらかの方法」で FILE 構造体を構築してそのアドレスを返すものであるということだけ知っていれば
普通のプログラマにとって十分なように出来ている。
169:デフォルトの名無しさん
23/12/05 10:36:22.34 NYBtRI3Y0.net
>>165
3行目から4行目の理解で大体あってるよ
それ以降は何言ってんのか分かんねーから全部アタマの中から破棄していいよ
正確にはFILEってのは抽象データ型であんたは構造体って言ってるけど構造体かどうかは分からんし使う側は知る必要もない
提供者がわざわざ抽象型にして使い手側の負荷を下げてくれるとこを中身がどうとか役割がどうとかさぐんのは筋が悪いんだよ
使えって言われてんだから何も考えずにだまって使えばいいよ
170:デフォルトの名無しさん
23/12/05 11:08:08.12 h96fo3nj0.net
FILE構造体ってOS毎に変わるし、コンパイラ実装でも又変わってた様な気がする
171:デフォルトの名無しさん
23/12/05 12:35:58.10 4VzMioa/0.net
FILE*経由だとバッファリングされるから、バッファーのポインタとそこに含まれてるデータサイズも含んでいるだろう
そもそもファイルのシーク位置も含まれてる
まとめると
・ファイルディスクリプターやファイルハンドル
・シーク位置
・バッファー(ポインタ、サイズ、含まれてるデータサイズ)
となるかね
172:デフォルトの名無しさん (アウアウウー Sa21-wVFe)
23/12/05 15:39:55.92 QJai9ytva.net
>>160
void *hoge = (void *)fopen("hoge", "wb");
fprintf((FILE *)hoge, "hoge\n");
fclose((FILE *)hoge);
173:デフォルトの名無しさん (ワッチョイ 71cf-L1V1)
23/12/05 17:31:14.53 4VzMioa/0.net
FILE*互換の自前のストリームを実装できれば便利なんだがなぁ
継承が無いから、構造体に自前の関数をセットして、何らかの登録関数に渡す感じになるだろう
174:デフォルトの名無しさん (JP 0Hf9-8IwF)
23/12/05 17:40:17.96 oSX0a7FoH.net
fopencookieとかfunopen
175:はちみつ餃子 ◆8X2XSCHEME (ワッチョイ 2a3e-By03)
23/12/05 17:48:30.74 z5PiblaY0.net
パイプのインターフェイスをストリームとして開くことが出来るから
適当なスレッドを開いてパイプの受け取り口で受け取った情報を好きなように加工するようにすれば、
パイプに書込む側ではストリームに書き込んだらいい感じに処理してくれるように見える。
というのを Windows でやっているのをどっかで見た。
176:デフォルトの名無しさん
23/12/05 18:11:37.45 GHHZLCc/d.net
>>165
開くだけで何が楽しいんだ?
読み取りも書き込みもクローズもできない
exitで自動的にクローズはされるけど…
>>163
HANDLEはポインタではなくただの整理券番号で実体は整数値だ
しかしWindows SDKでは「架空の構造体へのポインタ」として定義されているので例えばウィンドウハンドルをファイルハンドルと混同するとType mismatchエラーになる
これはかなり有用な仕組みでC言語が仕様に組み込んでほしいくらい
177:デフォルトの名無しさん
23/12/05 23:44:52.07 9c748LJ40.net
ソケットディスクリプタってファイルポインタに転生できる?
178:デフォルトの名無しさん
23/12/05 23:48:43.88 4UYj/sQ80.net
>>175
fdopen
179:デフォルトの名無しさん
23/12/06 08:34:18.09 hjosWl9s0.net
>>160です
皆さん大変参考になりました
今日はよく眠れそうです
180:デフォルトの名無しさん (スフッ Sd0a-nvfk)
23/12/06 12:07:25.67 dR0trs3yd.net
対策このままなら再発しそうね
URLリンク(japan.zdnet.com)
181:デフォルトの名無しさん
23/12/06 16:09:22.53 JLoh059d0.net
仕事なくなったら困る人が大勢いるし
182:デフォルトの名無しさん
23/12/06 20:24:47.29 tBrgYtLt0.net
free(NULL) は許されるのに
fclose(NULL) は許されないんよな
183:デフォルトの名無しさん
23/12/06 21:05:20.14 gHtrZlY5a.net
>>180
さらにfflush(NULL)は許されるという一貫性の無さ
184:はちみつ餃子
23/12/06 21:19:13.20 +44Bjs460.net
fflush の場合は全てのストリームを対象とするという特別なフラグとして NULL を活用しているので無効なポインタとしての NULL とは事情が違う気がするね。
それにしたってNULL を多義的に使っているという意味では一貫性はないけど。
185:デフォルトの名無しさん
23/12/06 21:23:39.94 bAVe0RWP0.net
free(NULL)は、おバカなマの為に特別に許容したんだろ
186:デフォルトの名無しさん
23/12/07 02:17:45.58 NYiehhGh0.net
以前ネットでおすすめされていた「苦しんで学ぶc言語」の内容をしっかり理解する段階まできたのですが、次は何をすれば良いのでしょう。
猫でも分かるプログラミングも読んでみたのですが仕様が古すぎてトレースできないのと、私には作者さんの文章の作りが合わず困っています。
まずは簡単なソフトを作りながら学べればと思います。
入門書の次に読めるような本と、そこからアプリケーション開発のイロハが分かる本やサイトを教えていただけないでしょうか。
187:デフォルトの名無しさん (ワッチョイ ea79-4utE)
23/12/07 07:17:00.47 Y9iRVwaI0.net
↑みたいなのって目的ないのかね
今後C言語で特に何かやりたい事がないなら別に何もする必要ないよ
188:はちみつ餃子
23/12/07 08:27:05.09 wi0prF2i0.net
Cで現実的なアプリケーションを作るならホスト環境 (OS など) の事情は無視できないし、具体的な目標なく道筋は決まらないと私も思う。
何の情報もない他人に何かを勧めるというのはしづらい。
目標があるならその分野の既存のコードを「読む」という体験はためになるかもしれない。
実際のコードを見て意味がわからない部分があれば学習が必要な部分だというとっかかりになる。
189:デフォルトの名無しさん (ワッチョイ 6646-wNAC)
23/12/07 09:28:19.84 ++8K4NmJ0.net
>>184
> 「苦しんで学ぶc言語」
というのは、これ↓ ?
URLリンク(9cguide.appspot.com)
> 苦しんで覚えるC言語
であれば文法解説のようなので、ファイル操作をしてはどう?
cat コマンドを作るとか。
190:デフォルトの名無しさん (ワッチョイ 65ff-WD8q)
23/12/07 10:04:58.60 NYiehhGh0.net
>>186
Windowsソフトを制作して当方の業務を効率化できればと考えています。
「既存コード」を読むですか、なんだか英語学酒のようで気が滅入りますね>
>>187
失礼しました。「覚える」でしたか。
ファイル操作がどこまでを指すのかわかりませんが高低水準入出力はすでに可能です。
191:デフォルトの名無しさん (ラクッペペ MM3e-8Sbt)
23/12/07 10:23:42.82 aHfAXzyRM.net
業務効率の向上が目的ならC言語は回り道すぎる
他の言語選んだ方がいい気がする
192:デフォルトの名無しさん (ワッチョイ 1163-8qzv)
23/12/07 10:31:24.83 HPax2zCP0.net
ファイル操作の課題出してあげようか
指定した二つのDirにあるファイルを同期させる
単にコピーするのではなく、タイムスタンプの新しいものだけをコピーする
新しいSubdirできていたら、中味があればDirごとコピーする
とりあえずは、新しく作られてファイルの同期まで、
削除については考慮しなくて良い
193:デフォルトの名無しさん (ワッチョイ b501-sZSb)
23/12/07 10:39:50.34 3PWWuEZS0.net
>>188
>Windowsソフトを制作して当方の業務を効率化できればと考えています。
早速これに取り組んだ方が良い
実用するものを作る方がモチベになる
194:デフォルトの名無しさん (スプッッ Sdea-GtvU)
23/12/07 11:21:46.78 6u4iKMo7d.net
C言語のスレッドで言う事じゃないがC言語以外の生産性の高い言語を学んだほうがよさそう
195:デフォルトの名無しさん
23/12/07 11:56:53.00 QzDrEJVi0.net
>>184
CはOSのAPIを直接叩けることがメリットでもあるので、Linuxのプログラミング本を読んでコード書いてみるのが一番良いだろう
マルチプロセス、マルチスレッド、ソケットとか覚えるべき事は沢山ある
Cでやれば根本から理解出来る
196:はちみつ餃子
23/12/07 12:04:11.70 FWY3NSUg0.net
(事務作業などの?) 業務効率化が目的なら Power Automate Desktop の活用を考えた方がいいと思う。
効率化の最初の段階は解決すべき問題を見つけることで、これをきちんと一度で洗い出すのは大抵の場合に出来ない。
雑に作って運用しながら改善するという手順をとるのがのぞましいが、 C で書くとそういう柔軟な体制がとりづらい。
197:デフォルトの名無しさん (ワッチョイ 9a2b-ntmn)
23/12/07 13:30:05.55 zYUoekf60.net
「なにを作りたいのかが大事」ってのは良く分かるんだけど、普通の人が作りたいものって大抵Cじゃない方が…ってなっちゃうんだよな
198:デフォルトの名無しさん (ワッチョイ 65ff-WD8q)
23/12/07 13:42:19.21 NYiehhGh0.net
>>90
そういった事もできるんですねー
>>191
取り組みたいのは山々なのですがuiの作り方からわからないので入手できるバーションで解説されている書籍が欲しいところです。
>>192
基礎を大切にしたいのでcをはじめのうちは使っていきたいと考えています。
>>193
仰る通り根本を理解できればと思います。Linux本ですね。可能であれば簡単なものでおすすめを添えていただけないでしょうか。
>>194
グラフィック系のソフトを使う上で不便なところを楽したい、と言いますか
とにかく画像表示や文字列表示から進めていきたいと考えています。
前述の通り基礎を理解したいので可能であればcで作成したいのです。
199:デフォルトの名無しさん (ワッチョイ 3514-I4o8)
23/12/07 13:42:44.77 P4JhXVL60.net
WindowsアプリならCじゃくて、せめてC++にしておけ
200:デフォルトの名無しさん (ワッチョイ 6aa0-0M9k)
23/12/07 13:43:24.10 n9+uyfFo0.net
楽したい奴にはCは向かない
201:デフォルトの名無しさん (アウアウウー Sa21-wVFe)
23/12/07 14:18:01.05 wNl2TimYa.net
C++は変な癖がつく
Cの方が絶対良い
202:デフォルトの名無しさん (ワッチョイ b501-sZSb)
23/12/07 15:23:59.73 3PWWuEZS0.net
Cで全部書いてると大変だと思うよ
機能全部使わんでも良いからC++の方が現実的だよ
203:デフォルトの名無しさん (ワッチョイ 1163-8qzv)
23/12/07 15:31:37.34 HPax2zCP0.net
大変かどうかは、何を作るかによる
204:デフォルトの名無しさん (ワッチョイ b501-sZSb)
23/12/07 15:35:13.86 3PWWuEZS0.net
>>201
>>196を踏まえて大変だと思うよ
205:デフォルトの名無しさん (ワッチョイ 71cf-Gt6m)
23/12/07 16:19:14.82 QzDrEJVi0.net
>>196
自分はUNIX Cプログラミング(いわゆるライオン本)で勉強して、めちゃくちゃ為になったけど、さすがにこれは古すぎる
詳解UNIXプログラミング 第3版は間違いのない名著
ふつうのLinuxプログラミング 第2版はLinux向けだし初心者向け
Cで仕事をするようにはならないかもだけど、「ふつうの~」を理解出来て自分のものにすることがCを学ぶ意義だな
206:デフォルトの名無しさん (ワッチョイ 66ab-XaJC)
23/12/07 16:23:44.20 5AmCTrxW0.net
>グラフィック系のソフトを使う上で不便なところを楽したい
ソフト側でスクリプト等がサポートされてなければ
できることは連続するショートカットを 1プッシュでまとめて出す
キーロガー&再生系とか Joy2Key みたいなキーコード送出系ぐらいしか思い浮かばん
207:はちみつ餃子
23/12/07 17:03:32.49 FWY3NSUg0.net
>>196
具体的に対象になってるソフトの名前は言える?
モダンな設計の Windows 用ソフトが外部から制御するために公開するインターフェイスは
Component Object Model の技術をベースにしていることが多くて、
高度な開発環境の補助を得ながら使う分には便利なんだが
C から使おうとするとすごく面倒くさい。 (出来なくはないけど。)
ソフトが外部に対してインターフェイスを公開するのではなく
制御用のスクリプト言語を内蔵している場合もあるので
C でのプログラミングに詳しくなってもあまり役に立たないこともある。
もしも外部に対してインターフェイスを用意していないなら
ボタン操作のイベントを発生させるとかして制御する (つまりまさに人がする操作を代行させる) ということも可能だが、
それを可能にするような基礎技術というか Windows の動作モデルを理解したいのなら
「猫でもわかるWindowsプログラミング」はそれなりに有用だと思うよ。
私は書籍を読んだことは無いけどウェブ版は Windows がイベントを伝播させて操作させる構造を理解するのに十分な記述はある。
だけど、人が操作するときに Windows の中で何が起こっているのかを
初心者が根本から理解してきちんと使いこなせるまでになるハードルは割と高めなんだよ……。
Power Automate Desktop なら技術の根本を理解せずともそれが出来るようになってるし、
マイクロソフトが直接に提供していてしかも無料という神ソフトなのでオススメした次第。
UWSC とか AutoIt なんかも人気があるね。
208:デフォルトの名無しさん
23/12/07 17:15:58.47 ggcXWkJv0.net
関数のサイズというのは、関数の引数のサイズと同じと考えて良いのでしょうか?
中身に1万行使ってる関数があるとして、その1万行は関数のサイズとは全然関係ないんでしょうか?
構造体はなんとなく変数のバイト数の足し算なんだなってわかるけど、関数がピンとこないです・・・
209:デフォルトの名無しさん
23/12/07 17:18:59.29 Dmh4B19g0.net
プリプロセッサメタプログラミングを覚えてからc言語の開発は楽になったわ
前は同じようなデータ構造でたくさんモジュール作ってたからな
210:はちみつ餃子
23/12/07 17:34:07.95 FWY3NSUg0.net
>>206
関数をデータとして扱うことはないので「大きさ」は定義されない。
C の言語仕様的には「関数はオブジェクトではない」という扱い。
関数に対して呼び出し以外の操作をする方法はない。
関数ポインタで関数の場所を指すということは出来るが、
型システム的にちょっと特殊な扱いになっていて関数ポインタ経由で値を取り出したりも出来ない。
もちろん実際にはなんらかの形でメモリ上には存在するし、
長いプログラムは大きい可能性が高いけど。
実際にどうなってるのかは生成された機械語を見ればいいんでね。
211:デフォルトの名無しさん
23/12/07 17:41:37.50 VEE9aIzl0.net
>>206
質問文が謎すぎて、何を聞きたいのか解釈できない
関数のサイズって言ってるのがビルドしてできた実行ファイルのファイルサイズの事なら、コードの量が多ければ当然サイズは大きくなる
212:デフォルトの名無しさん
23/12/07 17:41:59.31 ggcXWkJv0.net
>>208
ポインタのアクセス条件でメモリのサイズ・型が明確になっていること
とあったので、関数ポインタもサイズや型が明確でないといけないなら
ちゃんとわかっとかないといけないと思ったのですが、関数の扱いはわかってる人から見ても特殊なんですね
ありがとうございます
213:デフォルトの名無しさん
23/12/07 18:04:20.91 Kvlx+aNw0.net
>>206
あなたはどういう文脈で「関数のサイズ」が気になった・話題になったの?プアな組み込みとか?
俺は「関数のサイズ」が気になった・話題になった覚えがない
まぁコンパイル後のコード量かなぁ、関数の行数は大きく関係する
引数はスタックに積むけど「関数のサイズ」とは言わない気がする
214:デフォルトの名無しさん
23/12/07 18:19:55.87 5AmCTrxW0.net
サイズ云々は
インクリメントしたときにどんだけ(何バイト)進むのかが確定してる型でないとポインタにならない
→ じゃ関数ポインタって 関数のサイズ(≒ コンパイル後の機械語化されたバイナリのサイズ) を知ってるのか?
こういう思考の流れかな?
215:デフォルトの名無しさん
23/12/07 19:14:37.61 ggcXWkJv0.net
>>212
まさにそれです!
関数ポインタを配列に格納した時インクリメントしたら何バイト進むのか分かってないといけないのではと
216:デフォルトの名無しさん (ワッチョイ 8a71-yDrh)
23/12/07 19:46:05.37 Avn/NPEq0.net
>>213
その状況で必要になるのは関数のサイズじゃなくて関数ポインタのサイズや
それは他のポインタと同じ、64bitPCなら8バイト
仮定の話として、もし「関数ポインタの配列」ではなく「関数の配列」が作成できるような言語仕様にするなら、関数のサイズも決めないといけなかっただろうね
217:デフォルトの名無しさん (ワッチョイ c55f-tBUZ)
23/12/07 19:58:53.01 ggcXWkJv0.net
>>214
言われてみたらたしかにそうですねなんでポインタなのに普通の変数のように考えてしまってたんだろう・・・
218:デフォルトの名無しさん (ワッチョイ 9140-JrwL)
23/12/07 21:12:50.21 fQltjmnX0.net
void*使えるやん
219:デフォルトの名無しさん (ワッチョイ 65ff-WD8q)
23/12/07 21:34:16.53 NYiehhGh0.net
>>203
ありがとうございます。
>>204
メインのソフト除いて二窓三窓しているので欲しい機能だけ載せたソフトを自作したいなと。
>>205
204へのレスと同じです。
猫でも分かるは説明していない単語が出てきたり、UI作成の手順をトレースできなかったり
わからない人向けではなく分かる人向けの解説のようで個人的には合いませんでした。
220:はちみつ餃子 ◆8X2XSCHEME (ワッチョイ 656b-1gjz)
23/12/08 03:48:38.29 tzfGEsy80.net
>>216
関数ポインタは void* に格納可能であると保証してないし、関数ポインタがオブジェクトを指すポインタより大きかったり表現が異なっていたりする環境はある。
出来る環境でなら使うのが悪いわけではないけど移植性は犠牲になる。
221:デフォルトの名無しさん
23/12/08 06:53:57.90 Mdse7dEX0.net
>>218
>関数ポインタは void* に格納可能であると保証してないし
そんなことありえるの?
222:デフォルトの名無しさん
23/12/08 07:01:37.37 g0YSKcXt0.net
near ポインタモデル?だったかの
変数のアドレッシングサイズと
プログラムカウンタのアドレッシングサイズが違うやつ
223:デフォルトの名無しさん (ラクッペペ MM3e-VttM)
23/12/08 07:38:56.35 qsjd2ZYcM.net
ミディアムモデルとかコンパクトモデルとか
まぁ過去の話だわな
224:デフォルトの名無しさん (スップ Sdea-b4p5)
23/12/08 07:57:53.16 m+qJyEe4d.net
関数のサイズは関数のポインタをアドレス順にソートすれば求められる
そのサイズ分を実行可能領域にコピーすれば当然実行もできるよ
dllインジェクションとかでたまに使われる
225:デフォルトの名無しさん (スップ Sd0a-Cw2Y)
23/12/08 08:01:58.55 ClTGg8d6d.net
>>217
業務で使ってるような信頼性のソフトを自作するつもりなのか
一人で?予算は?期間は?
まあ無理だろ
単純にメモリの大きなPCに買い替えればいいんじゃない
226:はちみつ餃子
23/12/08 09:53:49.26 B2zBKDAb0.net
>>217
マイクロソフトが出している公式のチュートリアルは C++ が基礎だけど
考え方としては C でも同じなのでそのへんは適当に読み替えながら……
URLリンク(learn.microsoft.com)
Win32 API は C で使ってもそんなに不便ではないよう�
227:ノ出来てる。 特に最も基礎のこのへんの例示のコードは (C++ とは書いてあるが) たぶん C としてコンパイルさせても通る。 https://learn.microsoft.com/ja-jp/windows/win32/learnwin32/your-first-windows-program 必要な知識の分量は初心者が想像するよりずっと多いと思う。 分かりやすいドキュメントがあったとしても (そして無いこともしばしばある!) 分量は減らないので 分量というハードルをクリアするのは単純に学習量しかないし、 学習量をこなすには時間をかけるしかしょうがない。 やりたいことを自由に出来るようになるまで何も生産しない時間 (業務なら人件費に換算されるだろう) をかける余裕があるの? というところを不安に思っちゃうわけだよ。 ここは C スレだから C プログラミングを支援したい気持ちはあるがそれがしんどい場合も多いってことも知ってる。 個人事業なら趣味と兼ねるのもアリかもしんないけど。
228:デフォルトの名無しさん
23/12/08 10:13:43.24 20YRNN5F0.net
>>224
Cコンパイラに、C++ -> C トランスレート機能あるの?
229:デフォルトの名無しさん
23/12/08 10:26:10.76 vLixVDpZ0.net
API はほとんど C インターフェースで
C++をベターCとして利用してて C++のクラスの機構はほぼ使ってない
(GDI+ とかAPIがはなっから C++ インターフェースの奴は別)
230:デフォルトの名無しさん
23/12/08 10:34:54.49 faKtyhh20.net
>>218
ねえよ
231:デフォルトの名無しさん
23/12/08 10:50:23.47 k3Bpg+TDa.net
ぶっちゃけGDI+もCから使えるけどね
232:デフォルトの名無しさん
23/12/08 10:53:01.67 vLixVDpZ0.net
>>228
あれ Cインターフェース居るのか 最終的にはCOMになってるんやっけ?
233:デフォルトの名無しさん
23/12/08 11:03:20.25 Mdse7dEX0.net
>>220-221
なんかそういうのあったかも
234:デフォルトの名無しさん
23/12/08 11:04:41.36 VEgZ7oNC0.net
あれはPascalの呼出ではなかったかな
235:はちみつ餃子 ◆8X2XSCHEME (ワッチョイ 2a3e-By03)
23/12/08 11:27:29.89 B2zBKDAb0.net
>>229
gdiplus.dll 自体は関数群を置いてあるだけっぽい。
それをラッパークラスで覆って C++ から使いやすくしているだけ。
236:デフォルトの名無しさん
23/12/08 12:03:08.97 7hcazM9a0.net
>>224
兼任ですが個人事業主でお金と時間はそれなりに自由に使えます。
3~5ヶ月くらいはまとまった時間を取ることも可能です。
公式チュートリアルは参考にはなりますが読みやすいかと言われると微妙ですね。
知識はもちろん身につけたいのですが、そこまでの道筋は他人のコードを読む方がやはり良いのでしょうか?
書籍やサイトなどでアプリの形になるまでのチュートリアルなどは無いのでしょうか。
237:デフォルトの名無しさん
23/12/08 12:17:34.25 k3Bpg+TDa.net
Win32APIというよりそれ以前の
C言語の知識が足りてないんじゃないのかな
238:はちみつ餃子 ◆8X2XSCHEME (ワッチョイ 2a3e-By03)
23/12/08 13:05:38.60 B2zBKDAb0.net
>>233
何を学べば良いかすらわからないときのとっかかりとして
他人のコードを読む (何がわかってないかはわかる) ことを勧めたまでで、
良い資料があるならそれを読むにこしたことはないよ。
良い資料がないことも多いという現実はあるけど。
私は公式チュートリアルは良いほうだと思う。
知らないことを書いてあるんだからある程度は読みづらいこともあるのは当たり前のことで、
どれを読んだって似たようなもんじゃないかな。
専門的な内容をスラスラ読めるほうがおかしいでしょ。
239:デフォルトの名無しさん (ワッチョイ 8a80-yDrh)
23/12/08 13:11:55.82 0BufPgxy0.net
さてはオメー
ふらっとC#スレで他人のコードの読み方とか延々聞いてたヤツだな?
240:デフォルトの名無しさん (アウアウウー Sa21-/D3x)
23/12/08 13:15:41.58 o54AonyOa.net
>>206
関数もメモリにロードされるのわからず?
関数はただのマシンコードなんだからここから始まりますよ、というラベルがついてるだけだぞ
そして呼ばれた時はそこへジャンプするだけ
関数ポインタはそのマシンコードのラベルのアドレスを保持しているだけ
ポインタ以前にコンピュータの仕組みからやった方が良さそう
プログラム格納方式とか聞いたことない?
241:デフォルトの名無しさん
23/12/08 13:31:18.44 k3Bpg+TDa.net
>>236
なんちゃらGPTがここでこっそり質問してたら笑う
242:デフォルトの名無しさん
23/12/08 13:36:30.72 SLmq2FCH0.net
>>227
ググってみたらどうも>>218が正しいらしい
243:デフォルトの名無しさん (ワッチョイ 9140-JrwL)
23/12/08 15:42:45.24 faKtyhh20.net
だからねえよ
そいつが勘違いしてるか、使い方が悪いかだろ
244:デフォルトの名無しさん (ワッチョイ 5df0-/D3x)
23/12/08 16:03:05.13 abnVL6FT0.net
>>206
構造体もプログラムからしたらただのメモリ領域の塊だぞ
そこに変数とかいう概念はない
構造体のメンバのオフセットでその位置を指定して書き込んだり読み込んだりするだけ
その時のオフセットの計算に利用されるのが型
変数宣言すると構造体全体サイズのメモリ領域がスタックに確保される
mallocで確保されるとヒープに確保されてそのアドレスが返る
ただそれだけ
245:デフォルトの名無しさん (アウアウウー Sa21-wVFe)
23/12/08 16:08:12.70 k3Bpg+TDa.net
関数を malloc で確保するにはどうすれば良いですか?って言いそう
246:デフォルトの名無しさん (ワッチョイ 5df0-/D3x)
23/12/08 16:21:49.56 abnVL6FT0.net
ちなみにメモリにロードされた関数の領域は現代のOSならば当然ながらアクセス不可能
昔はプログラム領域にアクセスできてその中のコードを動的に書き換えるという荒技をやってた人もいるらしいが
247:デフォルトの名無しさん (ワッチョイ 5df0-/D3x)
23/12/08 16:24:27.68 abnVL6FT0.net
ちなみにメモリ領域にマシンコードを生成してそのメモリ領域のマシンコードを即時実行するということはできる
これをJITという
最近のスクリプト言語ではこの手法がかなり用いられている
やり方は普通にメモリにマシンコードを生成して実行可能属性を付加、各種CPUキャッシュをクリアしてから
関数ポインタにキャストして実行するだけ
248:デフォルトの名無しさん (ワッチョイ 1163-8qzv)
23/12/08 16:31:30.89 VEgZ7oNC0.net
メモリ保護機構が動いて実行できないと思う
16ビットリアルモードOSだったらできたと思うが
249:デフォルトの名無しさん (スッップ Sd0a-GtvU)
23/12/08 16:51:01.76 9cA1ls6dd.net
mprotectとかVirtualProtectで実行可能にすればできる
250:デフォルトの名無しさん (ワッチョイ 1163-8qzv)
23/12/08 17:06:26.65 VEgZ7oNC0.net
しかし、それだと任意のコード実行が自由自在ってことになって・・・
まずくない?
251:はちみつ餃子 ◆8X2XSCHEME (ワッチョイ 2a3e-By03)
23/12/08 17:24:04.59 B2zBKDAb0.net
>>247
許可を与えないと実行できないから問題にならないよ。
許可を与えられる前には実行できないんだから
外から注入されたものが自分で許可を出すということは出来ない。
252:はちみつ餃子 ◆8X2XSCHEME (ワッチョイ 2a3e-By03)
23/12/08 17:24:33.32 B2zBKDAb0.net
>>247
許可を与えないと実行できないから問題にならないよ。
許可を与えられる前には実行できないんだから
外から注入されたものが自分で許可を出すということは出来ない。
253:デフォルトの名無しさん (ワッチョイ 1163-8qzv)
23/12/08 17:35:36.56 VEgZ7oNC0.net
セキュリティって、身内も信じちゃまずいと思うよ
254:デフォルトの名無しさん (ワッチョイ eaad-snvD)
23/12/08 20:25:30.65 Bb4hYLfH0.net
>>250
その理屈はOSすら信じられずPC使うなって発想にしかならん
信じた者が信じる者は正しい、セキュリティの基本やろ
255:デフォルトの名無しさん (ワッチョイ 1163-8qzv)
23/12/08 20:31:27.89 VEgZ7oNC0.net
企業でもそうなんですか?
管理者が望んでいないプログラムが動かせたら困るでしょう
管理者自身がやるってならちょっと違いますが
256:デフォルトの名無しさん (ワッチョイ eaad-snvD)
23/12/08 20:41:26.51 Bb4hYLfH0.net
>>252
それはつまり「身内じゃないから動かない」なわけで身内も信じちゃまずいにはならんわけよ
>>249ではちみつ先輩が言っているのは「許可されたものは動く」なわけで
管理者が許可したものは動くし許可しなければ動かない
たぶん「許可したプログラムが許可してないコードを実行したらどうすんの?」ってことだと思うけど
そんなプログラムを許可した時点で間違ってる
257:はちみつ餃子 ◆8X2XSCHEME (ワッチョイ 2a3e-By03)
23/12/08 20:48:50.56 B2zBKDAb0.net
???
私の理解だと >>247 は「機械語をその場で生成して即時実行するのって危なくないの?」という話だと思ってたんだけど違うの?
そういう理解だったから実行の許可を出す (メモリの実行可能属性を ON にする API を呼び出す) ことなく実行できない、
プログラマの意図しない実行は防がれるということを応えたつもりだったんだけど、運用の話なの???
「身内」ってのは「プログラムの中での機械語生成にミスったらめっちゃ暴走するやん?」という意味かと思ったけど
運用にかかわる人物という意味?
258:デフォルトの名無しさん (ワッチョイ ea79-4utE)
23/12/08 21:24:15.38 8rS6bPls0.net
>>225
C++黎明期はC++トランスレーター付きのCを普通に使わされたもんだよ
259:デフォルトの名無しさん
23/12/09 07:42:54.58 Z2D8kHNzd.net
>>250
それなら自作のプログラムをコンパイルして実行できる環境がすでにまずいだろw
パソコンをゲーム機みたいにしたいのかい
読み書きできるメモリを実行可能属性にできるというだけで
書き込み不可能なシステムメモリに書き込めるようにできるわけではない
260:デフォルトの名無しさん
23/12/09 08:06:29.62 NnZXyC0n0.net
本日のWebは、
・帝乃三姉妹は案外、チョロい。 → 本誌で既読
・レッドブルー → 本誌で既読
・からかい上手の高木さん → ゲッサンで既読
どうにかしてよ、A立。たとえば響5巻無料Webでもとか。
そういえば、高木さんの人の将棋のやつ、マガポケでも終わったね。
261:デフォルトの名無しさん
23/12/09 08:12:11.03 zYR2UmFI0.net
いわゆるroot権限が必要な行為は実行出来ないね
でも、mprotectの説明によると
> 注意
Linux では、(カーネル vsyscall 領域以外の) 任意のプロセスアドレス空間において mprotect ()を呼び出すことが、常に許されている。
となってるから、Node.js(node)とかJITを行うプログラムがユーザー権限で動くのだろう
単に利便性の為だろう
262:デフォルトの名無しさん
23/12/12 20:44:31.35 3wiw5swR0.net
staticグローバル変数を含んだ動的ライブラリーを動的リンクをする場合はグローバル変数が初期化されるのはmain実行前の認識です。
同じプロセス内で再度初期化したい場合は別途初期化の関数を用意してないと不可能でしょうか?
動的ロード(dlopen)を使用した場合はdlcloseして再度dlopenした場合は初期化されますか?
263:デフォルトの名無しさん
23/12/12 21:01:30.67 bMo3JLCK0.net
>>259
やってみれば?
264:デフォルトの名無しさん
23/12/12 21:15:07.81 6C/zc+S/0.net
明示的に初期化処理を書くのが吉
265:デフォルトの名無しさん (ワッチョイ d701-Qbcu)
23/12/12 21:58:30.38 bMo3JLCK0.net
>>259
>動的ロード(dlopen)を使用した場合はdlcloseして再度dlopenした場合は初期化されますか?
Linuxの場合には初期化されたけど環境依存かも?
$ cat hoge.c hage.c
#include <stdio.h>
static int a = 100;
void increament_a () {++ a;}
void print_a () {printf ("%d\n", a);}
#include <dlfcn.h>
typedef void (*Func) ();
int main () {
void *handle;
Func func;
handle = dlopen ("libhoge.so", RTLD_LAZY);
func = (Func)dlsym (handle, "print_a");
(*func) ();
func = (Func)dlsym (handle, "increament_a");
(*func) ();
func = (Func)dlsym (handle, "print_a");
(*func) ();
dlclose (handle);
handle = dlopen ("libhoge.so", RTLD_LAZY);
func = (Func)dlsym (handle, "print_a");
(*func) ();
return 0;
}
$ gcc -shared -fPIC -o libhoge.so hoge.c
$ gcc -o hage hage.c
$ LD_LIBRARY_PATH=.; ./hage
100
101
100
266:デフォルトの名無しさん (ワッチョイ 9f07-h0RM)
23/12/12 22:04:40.47 3wiw5swR0.net
>>261
ですよねぇ
数十万のレガシーコードで、リセットするにはプロセスのキルが前提なんだけど、移植対象のシステムはプロセスをキルできないので、なんとかリセットする方法はないかと…
267:デフォルトの名無しさん (ワッチョイ 17f1-tASO)
23/12/12 22:10:06.55 6C/zc+S/0.net
初期値代入くらい書くだろ普通
処理系によっちゃ不定な値から始まったりするのを防ぐ為にさ
268:デフォルトの名無しさん (ワッチョイ 9f07-h0RM)
23/12/12 22:18:02.98 3wiw5swR0.net
>>262
検証ありがとう
自分の環境でも試してみます
269:はちみつ餃子 ◆8X2XSCHEME (ワッチョイ 5705-ZkkM)
23/12/12 22:18:21.71 Kje9ktjN0.net
>>259
RTLD_NODELETE フラグで再初期化を止められる(というよりアンロードを妨げるのだけど)ので逆に言えば特に指定しなければ再初期化はされるのが通常動作という解釈でいいと思う。
>>263
わかってるだろうけどレガシーコードをそうやって延命させるとますますワヤになるでよ。
270:はちみつ餃子 ◆8X2XSCHEME (ワッチョイ 5705-ZkkM)
23/12/12 22:39:58.31 Kje9ktjN0.net
>>264
言語仕様的にはグローバル変数 (記憶域期間が static) が不定になったりはしないことになっている (初期化子がなければゼロで初期化する) のでまともな開発環境があるところではそんな心配はしないよ。
心配が必要になるほど不確かな処理系しかない (または初期化処理も自分でかかなきゃいけないような低レイヤ) 分野もあるのは知ってるけどそれが普通ってことはない。
271:デフォルトの名無しさん (ワッチョイ 9f79-1KRD)
23/12/12 23:05:45.63 I4UWTUvH0.net
>>267
言語仕様ではなく2度目のdlopenの初期化の話なんだからドキュメント化されてないなら何の保証もないでしょ
272:はちみつ餃子
23/12/12 23:55:24.16 skpldDGw0.net
>>268
そういう意味で言ってたのならわかる。
「どうして元から代入する処理を入れてなかった?それが普通だろ?」というニュアンスで受け取ってたから元は dlopen しなおしで対処する想定ではなかったからそういうことを心配してなかった (する必要がなかった) という反応になった。
273:デフォルトの名無しさん (ワッチョイ 37f2-YdMO)
23/12/15 08:29:58.25 a4YsmFKj0.net
板の名前変わった?
274:デフォルトの名無しさん
23/12/17 18:23:47.21 kc2HrTf20.net
ポインタ変数にアドレスを代入するのはシャローコピーと言えると思いますか?
char s[] = "abc";
char *p = s; // shallow copy
275:デフォルトの名無しさん
23/12/17 18:40:34.16 i7ihHaq10.net
果たしてコピーと呼んで良い操作ナノか
276:デフォルトの名無しさん (ワッチョイ 1e5f-DkQ9)
23/12/17 19:27:43.64 mH/O4qym0.net
>>271
言えません
277:デフォルトの名無しさん (ワッチョイ e34d-e8vO)
23/12/17 19:32:39.54 MfQY7qyQ0.net
>>273
?
278:デフォルトの名無しさん
23/12/17 22:10:52.33 UmzU+/ux0.net
シャローコピーはディープコピーと並べて語るときに区別するための用語であって、
代入は普通に代入と呼ぶのが、コミュニケーションにおいて適切だ、
と、自分が聞かれた場合なら答えるし、レビュー依頼された場合なら指摘します
279:デフォルトの名無しさん
23/12/18 00:59:34.37 Mvyif4Hn0.net
>>275
シャローコピーと言えると思いますか?
280:デフォルトの名無しさん
23/12/18 00:59:46.13 Mvyif4Hn0.net
指摘する前に答えろよ無能
281:デフォルトの名無しさん (ワッチョイ 63c9-/1Gs)
23/12/18 02:31:45.63 BtLCMjh/0.net
シャローコピーでしょ
2つのポインタが同じ内容になってる訳だから
ちなみに、変数定義時の代入文はバインド(束縛する)と言った方が適切だな
282:デフォルトの名無しさん
23/12/18 09:17:00.35 qIC94rZG0.net
>>276
言えません
283:デフォルトの名無しさん
23/12/18 09:38:52.52 RUscEa1Z0.net
シャローコピーの要件からすると
ポインタ変数にアドレスを代入するだけでは成立せずに
リファレンス可能なオブジェクトを指してるポインタでないとまずい気がする
char *p = (char *)0x000; /* アドレスを代入してるぞ */
284:デフォルトの名無しさん
23/12/18 10:45:42.59 RHsCrDES0.net
意見分かれますね
ではstrdupはディープコピーだと言えますか?
285:デフォルトの名無しさん
23/12/18 10:52:49.41 kauj19Ts0.net
C言語にはオブジェクトと言う概念がないからなあ
お気持ちとしてどうかと聞かれれば、人それぞれで
286:デフォルトの名無しさん
23/12/18 10:54:27.09 PYgWDYAB0.net
いやそれぬるぽ
287:デフォルトの名無しさん
23/12/18 12:07:36.53 ccgmPeZz0.net
>>281
ファイルシステムや仮想記憶とか、コピーオンライトといって、書き込みが発生するまでは単なる参照先のコピーだけでコピー完了としてしまう
要するに何をもってコピーかを、先ずは定義してくれ
288:はちみつ餃子
23/12/18 12:57:51.87 vbeDxg2G0.net
それは C の概念モデルを前提にしていいだろ。
289:デフォルトの名無しさん
23/12/18 14:16:20.90 RUscEa1Z0.net
C++ の 参照だったら概念含めてそのまんまだったんだろうな
int a;
int& b = a;
290:デフォルトの名無しさん (ワッチョイ 12ad-9NgZ)
23/12/18 14:52:23.89 kcYk1zSZ0.net
>>271
言えると思う。
291:デフォルトの名無しさん
23/12/18 16:19:13.36 xiaHc48Fd.net
内容が値を表すメモリの位置 = オブジェクト
292:デフォルトの名無しさん (ワッチョイ cb62-dXDU)
23/12/18 17:05:11.17 pYYMlhZJ0.net
>>276
「言わない」
代入をシャローコピーだとか言ってなにか騒いでる人があなたの周りにいるという話?なら、そいつバカだからあなたは相手にしなくていいよ。あなたはもっと大事な問題に取り組むべき
293:デフォルトの名無しさん (ワッチョイ 4b63-3PPy)
23/12/18 17:09:52.77 kauj19Ts0.net
代入元の配列がスタック上なのかどうか、そちらの方がC言語的には重要
294:デフォルトの名無しさん (ワッチョイ 16ab-zIzn)
23/12/18 17:12:05.22 RUscEa1Z0.net
関数内の自動変数へのポインタを関数の外へ持ち出したりすると…
295:デフォルトの名無しさん
23/12/18 18:48:36.94 epkANb1d0.net
何かのポインタをメンバに持つ構造体の実体の複写
296:デフォルトの名無しさん
23/12/18 23:27:08.16 ccgmPeZz0.net
>>289
代入はコピーじゃないのか?
代入とコピーの本質的な違いは何だ?
297:デフォルトの名無しさん
23/12/18 23:33:27.08 a4PUOo8N0.net
コピーには違いないけどディープとかシャローとか区別できるものじゃないってことだろ
298:デフォルトの名無しさん
23/12/18 23:40:20.33 6hD73gHu0.net
>>293
代入は演算の種類
コピーは演算した結果起こる作用
用語を論理的に整理できてないとお話にならないだろう
RustvsC++スレ辺りでまともな議論ができてないのはこれのせい
299:デフォルトの名無しさん
23/12/19 08:23:42.15 ijJJQ5/r0.net
>>295
そういうコトなら、>>271は
アドレスを代入演算した結果を、シャローコピーと言えるか、
という質問じゃないの?
300:デフォルトの名無しさん (スププ Sd32-3CSV)
23/12/19 09:34:26.09 +6PK9xZxd.net
シャローコピーとかディープコピーとかはもともとPythonの概念ですよね?
301:デフォルトの名無しさん (ワッチョイ 2701-NGr8)
23/12/19 09:54:57.24 hCROhcq70.net
は?
302:デフォルトの名無しさん (ワッチョイ 2701-3PPy)
23/12/19 10:05:08.86 cwbunCZy0.net
>>289
馬鹿ってすぐ断定するよな
303:デフォルトの名無しさん (ワッチョイ 77cd-UNLj)
23/12/19 10:07:03.49 KoTx3gw20.net
コピーとクローンは違うよな?
304:デフォルトの名無しさん (ラクッペペ MMde-Y9Ov)
23/12/19 10:13:44.25 MIravlrKM.net
>>297
C++やJavaあたりが元だと思うけど
305:デフォルトの名無しさん (ワッチョイ 4b63-3PPy)
23/12/19 10:17:05.18 gboy58yC0.net
そういうことで、
Cにはシャローコピーとかディープコピーとかの概念はない
306:デフォルトの名無しさん (ワッチョイ cb62-dXDU)
23/12/19 10:51:12.24 E9BI8x9B0.net
少し前までスマートな人がたくさんいたのにいつの間にかバカしか居なくなった
307:デフォルトの名無しさん (ワッチョイ cb62-dXDU)
23/12/19 10:55:10.13 E9BI8x9B0.net
>>297
違います
308:デフォルトの名無しさん
23/12/19 11:32:45.68 df21V+Ma0.net
>>301
LISPじゃね?深いコピーは演習なんかの定番だった気がする
309:デフォルトの名無しさん
23/12/19 13:45:42.10 3Nu9QseCd.net
>>305
比較の手段が参照と値と構造とで数種類あるしそうだろうね
この手の大抵の起源はLispだよ
310:デフォルトの名無しさん
23/12/19 15:01:13.02 +6PK9xZxd.net
Pythonの解説書には大概、ディープコピーとシャローコピーが載ってますよ
311:はちみつ餃子
23/12/19 15:28:24.33 J0ExAcTK0.net
>>305
もちろんそういう状況を扱っている事例は数多くある。
ただ、ざっと見た感じでは古いマニュアルでは「再帰的」とか「共有」とかいった語で説明するのが普通っぽい。
深い/浅いといった言い方が発生したのはもっと新しい言語でのことだと思う。
312:デフォルトの名無しさん
23/12/19 19:44:57.82 cwbunCZy0.net
複オジが粘着してそう
313:デフォルトの名無しさん
23/12/19 19:48:51.51 KoTx3gw20.net
つか、Cは書いてる人にしか型が分からないからそんな器用な事は出来ないよな?
どっちのコピーも自前でちまちま作るしか無い
314:デフォルトの名無しさん
23/12/19 19:53:51.13 nmJwtfK30.net
呼称にこだわってる限りCなんて使えない
お上品な他の言語使ってりゃいいじゃん
315:デフォルトの名無しさん (ワッチョイ cbd5-dXDU)
23/12/20 05:56:32.08 r5p/Itr10.net
>>310
その通りですよ
私はユーザが定義する集成型(structみたいなもの)を、PCをまたいでリモートコンピュータ上にコピーするもの(WindowsのC#とHP-UXのC)、を仕事で作った事があるのだけど、それをやるには型定義からガッツリ関わる仕組みを構築しないと無理なのよ。
自分はエクセルでやった(そして完璧にはできず特例処理だらけになった)けど、普通はDDLとか独自に作るでしょ
上の方で最初に話題出したヒトは多分、どういう問題空間でディープコピーとかシャローコピーを話題にする必要が生じるのか【すら】分かってないよ
そうだね 複オジ とか言われてた人の雰囲気と似てるね
316:デフォルトの名無しさん
23/12/20 09:35:46.96 /uXb+00h0.net
UPLIFT プレミアム・サービスのお知らせ
URLリンク(uplift.5ch.net)
UPLIFT 主な特典
・連続投稿の規制を緩和します。
・スレッド作成時の規制を緩和します。
・5ch.netのスレッド表示画面に表示される広告を除去します。
・5ch.net専用ブラウザで5ch.netの過去ログを閲覧できるようになります。
・海外からのアクセス・ホスト経由からでも書き込みができるようになります。
・書き込みが規制されているプロバイダーからでも書き込みができるようになります。
・5ch.netを安定して利用できるように運営を支援できます。
5ちゃんねるを存続させるためには、皆様のご協力が必要です。
最後まで御精読いただきありがとうございました。
317:デフォルトの名無しさん (ワッチョイ e3f0-HAvR)
23/12/23 02:06:44.23 cGlPuzRM0.net
>>297
もちろん概念としてはCの時代からある
しかし明確に言葉として定義したのはsmalltalkのはず
shallowCopyメソッドとかがある
318:デフォルトの名無しさん
23/12/23 10:35:35.90 1vO40jtV0.net
smalltalk、凄いな!私はバートランド・メイヤーさん、すごく尊敬してます
javadocとかdoxygenみたいなシステムも、もうあの時代に彼はすでに形にして世に出してるんですよね
例外の説明とか、プログラムを契約の履行に例える話とかもそうだし、あとコメント論とかもイケてるんですよ
頭良すぎて周りが付いてくのに何年もかかってる気がする
319:デフォルトの名無しさん
23/12/23 10:43:58.55 1vO40jtV0.net
てかまあ、Cのスレだね
でもCで構造体リモートコピーするにはさ、みたいな話をしても、多分誰も乗ってきてくれないよね
320:デフォルトの名無しさん
23/12/23 11:24:31.92 MLKmoxlx0.net
それは話の持ってき方。プレゼン上手ならできる
321:デフォルトの名無しさん
23/12/23 11:28:28.28 j8bI1ONF0.net
そーゆーのに憧れてる層には土方言語のCはいらんだろw
322:デフォルトの名無しさん
23/12/23 11:41:06.10 PYuibGoS0.net
だからさ、C言語の変数や構造体内の型宣言なんてイイカゲンなんだからそう言う話ははなから無理なんだよ
323:デフォルトの名無しさん
23/12/23 11:42:27.32 1vO40jtV0.net
メッセージというか伝送パケットを作る話とかはどうですかね(皆さん興味ありますか)
タグ・レングス・バリュー形式がー、とか
バイナリvs文字列とか
(文字列にして伝送するのって遅いと思うでしょ、意外と速度okだったりします)
あと、message pack とか
324:デフォルトの名無しさん
23/12/23 11:44:11.18 PYuibGoS0.net
ゼロ(0x00)が送れないから文字列は無理
325:デフォルトの名無しさん
23/12/23 11:46:23.81 PYuibGoS0.net
経路によっては7ビット+パリティに解釈されるからバイナリは無理
326:デフォルトの名無しさん
23/12/23 11:49:57.82 PYuibGoS0.net
結局、デバイスとかハードの特性を理解する必要があるんだよね
327:デフォルトの名無しさん
23/12/23 11:54:07.08 MLKmoxlx0.net
メッセージの受け渡しでハードの特性まで理解する必要はないだろう
328:デフォルトの名無しさん
23/12/23 11:57:42.36 PYuibGoS0.net
だっていまどきC言語使ってる人なんて、デバイス寄りのハードウェアコントロールとか、チープなCPUに搭載するソフトとかだろ?
329:デフォルトの名無しさん
23/12/23 11:59:57.84 1vO40jtV0.net
>>321
おっと、反応サンキュー
0x00をデータとして送るのってあるある話題ですよねw
確かに「通信全部が」文字列で、nul文字終端だとすると無理。
でも、アタマにデータサイズがあって、それからデータがある形式ならば、仮に文字列が続いてると見える中に、まるでゴミ文字みたいに0x00が入っててもokなのよ
実は今のHTTPもそうなってたはず
330:デフォルトの名無しさん
23/12/23 12:04:44.24 PYuibGoS0.net
>>326
途中のコードに文字列操作を一切使わないならいいが
改修はいって文字列操作する人が居たらアウトだよね?
331:デフォルトの名無しさん
23/12/23 12:09:04.65 PYuibGoS0.net
最初からunsignd charのポインタとサイズを構造体にして扱えば良いだけ
332:デフォルトの名無しさん
23/12/23 12:09:04.99 1vO40jtV0.net
大昔は7ビットしか通らない経路あったねw
5baseとかの時代でしょうか
今は、8ビットを8ビットで伝送するほうが稀でしょうね
8ビットを10ビットで符号化することで、ゼロやイチが連続する数が少なくなるようにすることで、データ自体でタイミングを取れる方法をIBMが発明したとかで
だからこんなに速くなったそうです
333:デフォルトの名無しさん
23/12/23 12:13:58.12 1vO40jtV0.net
>>327
多分あなたの危惧が伝わってないです
改修案件でバグを作り込んだのに動作確認せずリリースしてしまうっていう事なら、工程管理ができてないって話でプロとしてダメ
メッセージ形式の仕様とは関係ないですね
334:デフォルトの名無しさん
23/12/23 12:17:04.95 1vO40jtV0.net
(…もしや「複オジ」さんだったかな?)
335:デフォルトの名無しさん
23/12/23 12:56:43.79 j8bI1ONF0.net
やっぱりめんどくさい奴だったかw
あんたにレスがもらえないのはテーマのせいじゃないとわかれ
336:デフォルトの名無しさん
23/12/23 18:17:03.63 PYuibGoS0.net
>>330
安易に文字列を使う仕様にしてるとバイナリ通らないの忘れるし思わぬバグを生む原因になるから、最初からバイナリ配列にするか文字列操作関数を一切使わない様にしないとな
337:デフォルトの名無しさん (ワントンキン MM07-TKg5)
23/12/24 00:00:50.96 B84K7ZI6M.net
>>332
うん…(悲しい)
338:デフォルトの名無しさん (ワッチョイ 4602-UkJf)
24/01/05 10:30:41.51 ph0QLfWd0.net
Perlとかで利用している設定ファイルがあるのですが、
Cで書いたプログラムでも同じファイルを設定ファイルとして読み込みたいです
設定ファイルですが、このような感じです
val = abc
str1 = $val/AAA
Perlでは「$val」を展開し、str1に「abc/AAA」と設定してくれるのですが、
Cから読み込む場合は、自分で展開する必要があると思ってます
それをやってくれるライブラリや関数等、ありますでしょうか
339:デフォルトの名無しさん (ワッチョイ e563-7PFe)
24/01/05 10:49:08.39 xgizPOi+0.net
その程度なら、自作できるだろう
340:デフォルトの名無しさん
24/01/05 11:38:06.91 VxELzJcZd.net
#define val abc
341:デフォルトの名無しさん (スププ Sd62-Blk0)
24/01/05 12:10:00.56 VxELzJcZd.net
enum { val = abc }
342:デフォルトの名無しさん (スププ Sd62-Blk0)
24/01/05 12:13:38.69 VxELzJcZd.net
enum の方はエラーになる
343:デフォルトの名無しさん (スププ Sd62-Blk0)
24/01/05 12:27:56.38 VxELzJcZd.net
#define もエラーになる
344:デフォルトの名無しさん (スププ Sd62-Blk0)
24/01/05 12:30:33.41 VxELzJcZd.net
#define val "abc"
345:デフォルトの名無しさん (ワッチョイ 651a-R/a6)
2024
346:/01/05(金) 12:30:55.30 ID:qVR6C9yQ0.net
347:デフォルトの名無しさん
24/01/05 12:49:25.99 qVR6C9yQ0.net
>>335
別の解決案
・Cに優しい形式(右辺を全部展開した形で、イコール前後のスペースもなし)で吐き直すツールを、perlで作る
・自分で全部Cで作る
・lex/yacc を使って軽言語解釈ルーチンを作る
それぞれデメリットがあって、質問に直接答える「そういったライブラリはあるか」に一番合ってるのが、最後のlex/yaccだけど、それは一番バカらしい答えでもある。お好きに
348:デフォルトの名無しさん
24/01/05 12:51:00.35 qVR6C9yQ0.net
>>337
君、答える側になれる実力ないだろ
349:デフォルトの名無しさん
24/01/05 12:54:37.44 KwPCWpVD0.net
sscanfで読めばよかろうもん
350:はちみつ餃子
24/01/05 13:07:45.12 t0UUGhQq0.net
>>335
その説明では何をやりたいのか伝わってないので仕様書を書いてみて。
理想的なライブラリがあったとして、そのテストケースという形式でもいい。
曖昧模糊な要望だと説明が下手なだけでなく説明しようとしている内容が見当違いな可能性を疑う。
(いわゆるXY問題)
351:デフォルトの名無しさん (ワッチョイ 2eab-zkkm)
24/01/05 13:32:24.69 38bnxq2E0.net
Cのソースでその展開もどきを行いたいのか
Cで書いてるプログラムがとあるファイル食って文字処理するんだけど、同じことを実現したいのか
352:デフォルトの名無しさん (ワッチョイ 45bb-dhuT)
24/01/05 13:37:38.46 M4U6Kwpw0.net
>>335
これは実装するとなると簡易言語になっちゃうな
でも変数と変数参照だけだから大して難しくないよ
たぶん1000行ぐらいに収まる
353:はちみつ餃子 ◆8X2XSCHEME (ワッチョイ 823e-slPv)
24/01/05 14:59:38.28 t0UUGhQq0.net
どうしても既存の設定ファイルをそのま�
354:ワ使いたい、それを処理できるようなものが欲しいということなら そんな都合の良いものがあるわけない。 自分で書くしかしょうがない。 完璧にそのままのフォーマットでなくおおよそ似た機能があればよいなら TOML とか JSON とか YAML とかの広く使われているフォーマットを採用したほうが面倒が少ない。 Perl でも C でも処理できるライブラリがいくつもあるし。 これらには変数展開のような機能はないが、 設定ファイルで動的な操作を可能にするのは問題を引き起こしやすいと考えられていて、 アプリケーション側でやるかプリプロセッサでなんとかしたほうがよい。 (強いて言えば YAML のエイリアス機能は変数のようなものとも言えるけど文字列を結合したりは出来ない。) 逆に設定どころではなくユーザーによるカスタマイズをどんどんやってもらうようなものなら Lua とかのアプリケーション拡張言語を埋め込んでしまうという方法もとれる。
355:デフォルトの名無しさん (ワッチョイ c2b5-R5Zd)
24/01/05 15:39:37.20 mdj5x9Xd0.net
Perlにそんな便利機能あったっけ
356:デフォルトの名無しさん (ワッチョイ c6bb-bJ3A)
24/01/05 18:09:30.90 xFVV62H30.net
Cは遅延評価を積極的にやるための言語ではないからなあ
C++やC#ならあるんだけどね
lex/yacc はちょっと古くて
今なら flex/byson ですね
357:デフォルトの名無しさん
24/01/06 15:06:00.15 NPThFXTg0.net
$ の変数展開しかやらないなら複雑な構文解析にはならないから全部自作した方が楽なのでは?
少し楽したいなら perl に読ませて $ 展開させた文字列に変換して出力したのを C の側で読むとかね。そうすると少し楽ができる。
これの問題は perl が使えない環境では動かないことかな。
358:デフォルトの名無しさん
24/01/06 16:25:37.13 2Gstkfh+0.net
今なら packcc おすすめ
359:はちみつ餃子
24/01/06 16:27:28.51 iX+vez910.net
設定ファイルのデータ構造が key/value の組だけ、 value は単なる文字列という程度なら
パーサジェネレータはかえって邪魔じゃないのかな。
360:デフォルトの名無しさん
24/01/06 21:36:47.69 8zwGVkiA0.net
lex/yaccは使った事ない人にはハードル高いだろうね。逆に、使い方が分かると何でもそれでやりたがる時期が来る。どんなツールや言語でもそうだろうけど
361:デフォルトの名無しさん
24/01/06 21:39:52.15 YhaQaYGw0.net
BNF書いても大した量にならないだろうし俺ならフルスクラッチで書いちゃうな
362:デフォルトの名無しさん
24/01/06 21:45:36.68 8zwGVkiA0.net
で、設定ファイル、shで環境変数を設定すりゃ済む、という案に誰も反応してもらえないんだが、どうだい? windows ならcmdだろうけど
設定項目ってのは、パス文字列とか、メモリサイズとか、ほぼ固定だけどあとから変えたい場合もあろう、っていう定数だよね。環境変数ってまさにその目的だと思ってる。
ドル記号で一時値の展開もできる。Cからも簡単に読める。
363:デフォルトの名無しさん
24/01/06 21:56:18.04 8zwGVkiA0.net
shで、設定ファイル兼、実行ファイル起動ラッパを書いて、利用者には直接実行ファイルじゃなくラッパを起動せよと説明して
export XXX_ROOT=/var/xxx
export XXX_INPUT_DIR=${XXX_ROOT}/in
export XXX_OUTPUT_DIR=${XXX_ROOT}/out
export XXX_READBUF_SIZE=32768
exec ${XXX_ROOT}/bin/xxx
Cで読む処理は
get_conf_str(...) //文字列項目用
get_conf_i64(...) //整数項目用
どっちもパラメータに
(環境変数名, 環境変数が未設定時の具体値)
って指定する。これが、ソース上の1箇所でズラッと並ぶと「設定項目名とハードコード値の、一覧表」風になるの。分かる?
364:デフォルトの名無しさん
24/01/06 22:02:36.24 8zwGVkiA0.net
get_conf_str() と get_conf_i64() の中身は
getenv() を使って簡単に実装できる、のは分かるよね?
365:デフォルトの名無しさん
24/01/06 22:09:41.74 LvNnK4+W0.net
単なる文字列だけなら正規表現の置換でいいだろ
366:デフォルトの名無しさん
24/01/06 22:20:12.76 8zwGVkiA0.net
struct conf_t {
char* input_dir
char* output_dir;
int64_t readbuf_size;
} g_conf;
文字列項目はC++だとstd::string にする所だが、Cだとstrdup(的なもの)で実装しても良いんじゃないかい。
g_conf.inputdir = get_conf_str(
"XXX_INPUT_DIR", "/var/xxx/in");
g_conf.outputdir = get_conf_str(
"XXX_OUTPUT_DIR", "/var/xxx/out");
g_conf.readbuf_size = get_conf_i64(
"XXX_READBUF_SIZE", 32768);
とかってするとソース上で一覧表風になるでしょ。タブ文字も入れて桁そろえて。
367:デフォルトの名無しさん (ワッチョイ 627a-JKp6)
24/01/06 23:25:47.33 4fq2Cpkf0.net
まあ落ち着けよ 質問者はそんなこと聞いとらんだろうよ
368:デフォルトの名無しさん
24/01/07 00:35:50.01 yw4Ulg6E0.net
for(;;){
if((result = fgets(line, MAX_LEN, stream)) != NULL){
p1=result;
p3=p1+strlen(line);
p2=strtok(p1, "=");
}
}
これで、p1とp2から左辺、p2とp3から右辺が取り出せる。
$の展開は、マクロ展開処理の要領で
右辺に$があるかチェックして、あったら定義値に置き換えるという
10ステップ程度の処理でできるだろ。
369:デフォルトの名無しさん (ワッチョイ 7fb5-j9I8)
24/01/07 08:57:04.03 4P3NNejl0.net
>>335
>Cから読み込む場合は、自分で展開する必要があると思ってます
その通りです
>それをやってくれるライブラリや関数等、ありますでしょうか
ありません
自作する必要があります
>>363
p2=strtok(p1, "=");
スペースやタブの処理が必要
370:デフォルトの名無しさん (ワッチョイ 7f79-e2pS)
24/01/07 10:17:39.72 gAwkeLQQ0.net
せめて既存の気の利いた言語のstring型のメソッドやらを参考にしろよ
ここで再発明しても誰も使わんだろ
371:デフォルトの名無しさん (ワッチョイ 5f1a-nsdu)
24/01/07 10:25:56.11 TVg93ufA0.net
質問者、もういない
372:デフォルトの名無しさん (ワッチョイ df01-6482)
24/01/07 11:15:08.19 SfiTOIyR0.net
>>335
>それをやってくれるライブラリや関数等、ありますでしょうか
perlはCで書かれてるけどね
373:デフォルトの名無しさん (ワッチョイ 5f63-vNrU)
24/01/07 11:23:13.54 XrTF2oph0.net
動かすCプログラムをperlに書き直す方が簡単そう
374:デフォルトの名無しさん (ワッチョイ 7fad-ipwt)
24/01/07 16:24:59.67 tTa6vFrs0.net
こんな方法もある。しかし $ の変数展開しかしないなら無駄な感じはするね。それだけのためにここまでするのかという。
perlembed - C プログラムへの Perl の埋め込み方
URLリンク(perldoc.jp)
375:デフォルトの名無しさん
24/01/10 16:11:15.07 PVZRGcug0.net
$がリテラルとして入ってた時はどうするかとか、結構面倒そう
376:デフォルトの名無しさん (ワッチョイ 5f1f-nsdu)
24/01/10 17:49:56.37 C4OEbwTl0.net
>>370
そうなんだよー、真面目にやるとバカみたいに面倒なのよ
文字列リテラルの中に $ やコメント開始終了記号が入る事もあるし
コメントの中に $ や文字列開始終了記号が入る事もある
# "#"
$aaa = /* $コメント " */ "文字列/**/値";
なので、頭から読み始めて、状態を追いながら(現在の場所が 文を書く所か、コメント内か、文字列内か)読まないと、正しいファイルを正しく読めない
んで、つまんないバグを作り込んだりするの。その、もういない誰かが作り込んだつまんないバグを、別の誰かが直すはめになる。そんなの嫌じゃね?
377:デフォルトの名無しさん (ワッチョイ 5f1f-nsdu)
24/01/10 17:57:07.75 C4OEbwTl0.net
でも本当に、質問者はもうト
378:ンズラしたと思うよ。次の話をしよう
379:デフォルトの名無しさん (ワッチョイ 5f63-vNrU)
24/01/10 18:00:48.10 PVZRGcug0.net
次の患者さん、どうぞ
380:デフォルトの名無しさん (ワッチョイ ffcf-mfjK)
24/01/10 21:56:41.19 Qa3z5jue0.net
>>327
どっちにしろ質問者のためにやってるわけじゃないからいいんだよ
381:デフォルトの名無しさん (ワッチョイ 5ff5-j9I8)
24/01/10 22:25:04.83 Gs+Ha8Nh0.net
>>371
そこまでのコメント機能はいらんやろ
シェルスクリプトの設定ファイル程度のことができればいいんだろうから
#が来たら改行までをコメントとするぐらいで
382:デフォルトの名無しさん (ワッチョイ 7fd9-EKXI)
24/01/10 23:20:02.65 ZQ7M3ZpB0.net
ちなみにCの識別子に$を使える
少なくともgcc, clang, msvcで使える
int $val = 0;
とか
383:デフォルトの名無しさん (ワッチョイ 5f1f-nsdu)
24/01/10 23:20:30.43 C4OEbwTl0.net
>>375
環境変数設定で「十分」どころか、それがかなりきちんと対応している。
シェルは(shもcmdも)「改行までコメントとみなす」なんていういい加減な実装じゃないよ
384:デフォルトの名無しさん (ワッチョイ 5f1f-nsdu)
24/01/10 23:36:31.88 C4OEbwTl0.net
パーサー実装の現実的な話がまともにできるニキはここにはいないねw
385:デフォルトの名無しさん
24/01/11 02:31:42.07 uSDU2aBB0.net
ほらな、はちみつも黙るやろ
規格は詳しいけどな
386:デフォルトの名無しさん
24/01/11 02:42:19.58 WTkhFxto0.net
パーサーなんて大して難しくないよ
テスト書けば
387:デフォルトの名無しさん
24/01/11 06:03:54.69 ZajpDUJL0.net
>>377
いやだからそんな本格的に作る必要ないって話
労力の投入場所を選定するのもプログラマの能力
388:デフォルトの名無しさん
24/01/11 07:51:37.56 7oF58mtI0.net
>>371みたいなので悩むならさくっと正規表現ライブラリやパーサージェネレータ使うな。
学習のために自分でパーサー書いてみたいってんなら別だが。
389:はちみつ餃子 ◆8X2XSCHEME (ワッチョイ 7f3e-Cx9t)
24/01/11 09:41:05.64 NL5Kg7pj0.net
>>379
仕様が曖昧なのに実装の話をしても無意味だろ。
新しい情報が提示されないなら回答すべきこともない。
390:デフォルトの名無しさん (ワッチョイ 5f63-vNrU)
24/01/11 09:42:53.45 ZxeGb/wD0.net
誰か、作ってやれよ
391:デフォルトの名無しさん
24/01/12 10:13:36.22 Umd8uX9b0.net
strcat() はダメなの?
392:デフォルトの名無しさん
24/01/13 00:25:52.89 suyQO94R0.net
sscanfで十分だよ
393:デフォルトの名無しさん (スッップ Sd9f-j9I8)
24/01/13 09:14:54.62 mB7BPAPVd.net
>>385
参加したかったの?
394:デフォルトの名無しさん
24/01/13 09:41:46.29 fMrSPcrk0.net
ここに書けば参加したことになるよ
395:デフォルトの名無しさん (ワッチョイ 5f59-P7l0)
24/01/13 13:22:56.37 kmNIHanh0.net
参加することに意義がある
396:デフォルトの名無しさん (スッップ Sd9f-+zra)
24/01/13 16:53:47.66 8Ttuq2mzd.net
C言語からJSON読み書きにオススメのライブラリやDLL教えてくれさい。
UTF-8↔ANSI変換はAPIでやれそうです。
397:デフォルトの名無しさん
24/01/13 19:04:48.77 suyQO94R0.net
yyjsonで十分だよ
398:デフォルトの名無しさん
24/01/17 13:51:26.07 MxPcwzaVM.net
以下はmalloc()で割り当てた領域を開放してポインタをヌルポインタにするマクロである
#define MYFREE(p) do {free(p); p = 0;} while(0)
このマクロに不備があるかないか、ある場合はどんな不備か答えよ
ただし処理系はANCI C準拠とし、stdlib.hがインクルードされていることとpが左辺値かつmallocで割り当てた領域を指す有効なポインタであることの2点は呼び出し側によって保障されているものとする
399:デフォルトの名無しさん (ワッチョイ 427c-kX52)
24/01/17 16:32:50.55 sbbnyjB/0.net
宿題は他所でやれ
400:デフォルトの名無しさん
24/01/17 19:42:28.17 bWv2IYcS0.net
do-while文で回す意味ってあるの?
401:デフォルトの名無しさん
24/01/17 19:44:52.19 UA2B8Wur0.net
使った人に聞きなさい
402:デフォルトの名無しさん
24/01/17 19:49:06.18 dYqrLAA4M.net
>>394
セミコロンをつけさせるため
403:デフォルトの名無しさん
24/01/17 21:11:00.53 DTNbW1I/0.net
>>392
答えわかったけど教えない
404:デフォルトの名無しさん
24/01/17 21:21:33.14 Am4HUjmg0.net
>>394
2つ以上の文をマクロ関数の形にするときに、C言語の仕様において最も合法安全とされるイディオムだよ
405:デフォルトの名無しさん
24/01/17 21:47:57.64 i5GqHIkod.net
>>394
たとえば
#define MYFREE(p) free(p); p = 0
と定義すると
if( 条件 ) MYFREE( p );
と書くと
if( 条件 ) free(p); p = 0;
と展開されてしまいp = 0;は条件に関わらず実行されてしまう
またこの後にelse節が続くとエラーになってしまうなど不具合の原因になる
406:デフォルトの名無しさん (ワッチョイ f901-LNAd)
24/01/17 23:38:16.60 bWv2IYcS0.net
>>396,398,399
全然知らなかった
アリガト
407:デフォルトの名無しさん (ワッチョイ 2214-HXAs)
24/01/18 11:04:17.52 0zoYvNSM0.net
>>392
その条件下ならない
でもpが左辺値という前提がなかったら変なコトになるコードが書けるね
408:デフォルトの名無しさん (ワッチョイ 2214-HXAs)
24/01/18 11:04:49.16 0zoYvNSM0.net
>>400
396はゼンゼン関係ないんだけどホントに分かってんのか?w
409:400ではないが
24/01/18 12:19:02.31 5g03qqC30.net
>>402
396 と 399 は異口同音と読んでいたが、主旨違うの?
410:はちみつ餃子
24/01/18 12:27:08.35 LtdZIRKJ0.net
>>402
ブロックではなく do / while にする理由としては関係がある。
411:はちみつ餃子
24/01/18 12:41:36.76 LtdZIRKJ0.net
二つの文が分かれてしまわないようにするだけならブロックで包めばよくて
#define MYFREE(p) {free(p); p = 0;}
と定義しておけば
if( 条件 ) MYFREE( p );
というような使い方で意図通り動作する。 問題になるのは else が付くときで、
if( 条件 ) MYFREE( p );
else foo();
みたいなことをすると
if( 条件 ) {free(p); p = 0;};
else foo();
というように余計なセミコロンが if と else の対応付けを壊してしまう。
かといって MYFREE にはセミコロンを付けない使い方をせよというのも不格好なので do / while で囲むといい感じって話。
412:デフォルトの名無しさん
24/01/18 13:15:24.78 hXSenRUz0.net
はちみつ餃子はいい加減改名しろよ、はちみつ先生によ
どんだけタメになる話すりゃ気が済むんだ
目からウロボロスだぜまったく
413:デフォルトの名無しさん
24/01/18 13:17:33.34 opxINJAy0.net
>>392
「せよ」ってなんだよ。何様のつもりだ?
414:デフォルトの名無しさん
24/01/18 20:39:02.28 r48d/DyKd.net
#define MYFREE(p) (free(p), p = 0)
のほうが単純
415:デフォルトの名無しさん
24/01/18 22:45:02.99 twAiz/ys0.net
今どきのCならマクロじゃないといけない場合以外はinline使え。
416:はちみつ餃子
24/01/19 08:59:45.95 vjpbBz8R0.net
>>409
C の関数は多相化できない。
void* と他のポインタは相互に変換可能なんだが
void* 自体の表現や境界調整要求は環境依存なので
#include <stddef.h>
#include <stdlib.h>
inline void my_free(void** x) {
free(*x);
*x=NULL;
}
int main(void) {
int *x = malloc(sizeof(int));
my_free((void**)&x);
}
みたいなことをして正しく動作する保証はないはず。
この場合は「マクロじゃないといけない場合」だと思うよ。
417:デフォルトの名無しさん
24/01/19 11:12:10.18 Wkz3Ctqj0.net
mallocが返すのはvoid*だし、freeが受け取るのもvoid*なのに??
保証が無かったら俺達はこれからどうすればいいんだw
418:デフォルトの名無しさん
24/01/19 11:13:32.08 76FyHnUv0.net
printf("Hello, work!");
419:はちみつ餃子
24/01/19 11:18:44.53 vjpbBz8R0.net
>>411
void* の話じゃなくて void** の話をしてる。
420:デフォルトの名無しさん
24/01/19 11:42:42.67 THNGxTXR0.net
printf("Konyanyachiwa, Sekai no Kuni kara!");
421:デフォルトの名無しさん
24/01/19 12:11:49.63 Wkz3Ctqj0.net
void**とvoid*は相互に変換可能じゃないのか?
422:はちみつ餃子
24/01/19 12:19:49.22 vjpbBz8R0.net
変換が可能だということと同じ表現を持つことは別という話。
int* から void* への変換は変換に関するルールだが
int** から void** への変換によって int* を void* として読もうとするのは type punning の問題。
423:デフォルトの名無しさん
24/01/19 12:20:09.89 Wkz3Ctqj0.net
そうなると、
int** a = malloc(sizeof(int*) * 3);
は、保証無いことになるな
俺達はどうすればいいんだw
424:デフォルトの名無しさん
24/01/19 12:25:31.50 Wkz3Ctqj0.net
void** a = malloc(sizeof(void*) * 3);
の方が適切だったか
これで、a[0]の読み書きが保証されないのは困るよ
425:はちみつ餃子
24/01/19 12:27:15.27 vjpbBz8R0.net
>>417
繰り返すが変換の話と表現の話は異なる。
void* は全てのオブジェクトを指すポインタと相互に変は可能であることは保証され、
「malloc が返すポインタに限っては」いかなる型とも適合するように境界調整されていることが保証される。
426:デフォルトの名無しさん
24/01/19 12:34:27.05 3hcnICbb0.net
【AI】Googleの医療面接特化AI「AMIE」は人間よりも正確な診断が可能&患者への印象に優れるという研究結果 [すらいむ★]
スレリンク(scienceplus板)
【AI】Google DeepMindが数学オリンピックレベルの幾何学問題を解けるAIを発表、人間の金メダリストに近い性能を発揮 [すらいむ★]
スレリンク(scienceplus板)
【AI】大学入試共通テスト、3つのチャットAIに解かせてみたら? GPT-4はバケモノだった [すらいむ★]
スレリンク(scienceplus板)
【ナゾロジー】「株価の変動を粒子の振動として理解」量子力学で株式市場の法則を読む! [すらいむ★]
スレリンク(scienceplus板)
【AI】NTT、自分の分身AIを低コストで作る技術。自分の合成音声を簡単に作れる技術も [すらいむ★]
スレリンク(scienceplus板)
ボイス・トォ・スカルのコアプログラムの一部は上記を統合している
427:デフォルトの名無しさん (スッップ Sd22-aNQv)
24/01/19 12:39:29.69 S8ovIeWid.net
何を言ってるんだお前は案件
ポインタの中身は指す対象によってアラインが変わるが
ポインタ自体のアラインは原則一種類しかない
428:はちみつ餃子 ◆8X2XSCHEME (ワッチョイ 423e-/YAw)
24/01/19 12:51:29.04 vjpbBz8R0.net
>>421
ポインタは型ごとに異なる表現・境界調整要求を持つ可能性がある。
適合する型へのポインタ同士の場合など同じ表現・境界調整要求を持つ条件が定められているが
最後に「これ以外の型へのポインタは、同じ表現又は同じ境界調整要求をもつ必要はない」と仕様に明記されてる。
具体的な部分は処理系定義なので全部が同じ表現であることをあてにしていい環境ならそうすることは否定しなけど、
常にあてにできるわけでもない。
429:デフォルトの名無しさん (ワッチョイ 463f-ggGG)
24/01/19 13:18:44.56 Wkz3Ctqj0.net
そうは言っても、
void* p = 0;
と直接生成出来るわけで、void*は値としての意味もちゃんとある
それがvoid**にすると元に戻せる保証が無いのは仕様の不備だろw
430:デフォルトの名無しさん (スッップ Sd22-aNQv)
24/01/19 13:22:00.51 S8ovIeWid.net
>>422
それは「ポインタが指す対象」についての記述で
ポインタ自体にはどんな適当な値を書き込むことも可能(そのポインタを使ってアクセスすると何が起こるかわからないというだけ)
ただポインタにNULLを書き込むだけの関数になんの危険もない
431:はちみつ餃子
24/01/19 13:35:18.59 vjpbBz8R0.net
>>424
> それは「ポインタが指す対象」についての記述で
この (>>410) 場合はポインタが指す対象に書き込もうとしている話だが。
432:デフォルトの名無しさん (スッップ Sd22-aNQv)
24/01/19 15:18:43.59 S8ovIeWid.net
>>425
そのポインタは関数への引数であり
すでにvoid*を表すものだと型は決まってるではないか
それとは別に
インライン関数で書いた場合はその場で展開されるから
void* p = 0;と書いた場合と同様にコンパイラが適切な0を書き込んでくれるんじゃないの
つまり(void**)をつけると逆に危険
my_free(&x);
でよい
433:デフォルトの名無しさん
24/01/19 16:04:16.95 dJaf/W/GM.net
ポインタで0リテラルだけは特殊でNULLと同義だったのではなかったっけ
434:はちみつ餃子
24/01/19 16:16:34.10 vjpbBz8R0.net
>>426
> (void**)をつけると逆に危険
これは暗黙に型変換されることが保証される文脈ではないので付けなければコンパイルが通らないだけ。
(コンパイラによっては黙って通すことはあるのかもしれない。)
> インライン関数で書いた場合はその場で展開されるから
言語の意味論としてはインライン関数は
・ 同じ定義なら (翻訳単位を跨いだ場合でも) 複数回定義してもよい (定義が一回の場合と同じ挙動)
・ なるべく高速に呼び出して欲しいことを期待するヒントである (実現方法は規定しない)
ということになってる。
インライン関数がインライン関数ではない関数と異なる動作にはならない。
435:はちみつ餃子 ◆8X2XSCHEME (ワッチョイ 423e-/YAw)
24/01/19 16:39:47.61 vjpbBz8R0.net
>>427
せやで。
厳密に言えばリテラルだけじゃなくて「整数の 0 であるような定数 (定数式) をポインタに型変換したときは空ポインタ」というルール。
これも変換に関するルールであって表現に関するルールではないよね。
実際に空ポインタの内部表現が整数の 0 というわけではない環境は存在するが、
型が正しければ適切に変換される。
436:デフォルトの名無しさん (ワッチョイ 25bb-ggGG)
24/01/19 16:53:05.15 CCGmGKuQ0.net
>>429
それ規格書に書いてあんの?知らんかったわ
でも
if (!ptr)
みたいなポインタがゼロであることを期待するような式は処理系依存になるでしょ?
437:はちみつ餃子 ◆8X2XSCHEME (ワッチョイ 423e-/YAw)
24/01/19 17:02:59.57 vjpbBz8R0.net
>>430
いや、それがよく出来てて、ポインタをそういう形で条件に使うのは問題ない。
単項演算子 ! について「式!Eは,(0==E)と等価とする」というルールになっていて
等価演算子 (==) はポインタと空ポインタ定数を比較したときの結果を規定してる。
空ポインタ定数のほうをもう一方のオペランドの型に合う空ポインタに型変換するルール。
438:デフォルトの名無しさん (ワッチョイ 25bb-0zjl)
24/01/19 17:32:06.95 CCGmGKuQ0.net
>>431
規格書読んできたけど
6.3.2.3 値0をもつ整数定数式は空ポインタになる
6.5.3.1 式!Eは,(0==E)と等価
6.5.9 ==は空ポインタ定数をポインタの型へ型変換する
ってことか
なるほど、規格を解釈すれば!ptrは空ポインタと比較されることになるから問題ないのか
勉強になったわ
439:デフォルトの名無しさん
24/01/19 18:55:00.05 EWHtqHW90.net
NULLは処理系定義だしこの辺はややこしいよね
440:デフォルトの名無しさん (ワッチョイ 463f-ggGG)
24/01/20 00:57:56.71 QcwVnceA0.net
void*の値は作成出来るけど、表現や境界調整要求は未定義とか、おかしいだろ
Cは現実に則した言語だと思ってたけど、妙な未定義だな
ちなみに、インタープリター型言語を作ったら、オブジェクトはみんなvoid*になる
void*の配列を作成したりとか普通に行われる
もはや規格とか無意味
実装がどうなってるかだけが重要だ
441:デフォルトの名無しさん
24/01/20 10:29:05.14 ZDCHWjSD0.net
>>433
全然ややこしくないでしょ
442:デフォルトの名無しさん
24/01/20 10:30:19.13 UfD1Ji0o0.net
> 実装がどうなってるかだけが重要だ
もちろんその通りだけど規格上未定義なわけだから実装がすべて統一されているとは限らないわけで
その実装における「限らない」が問題なわけでしょ
443:デフォルトの名無しさん
24/01/20 12:47:01.09 Ttk7tIdd0.net
実際に使用する環境に合わせれば良いだけ
444:デフォルトの名無しさん
24/01/20 13:33:03.85 QcwVnceA0.net
各OS毎にABI(Application Binary Interface)が定義されてて、Cの規格で定義されてないところが明確に定義されてる
2つを合わせて現実のC言語なんだよな
だから、JIS X 3010だけを取り上げてどうこう言っても混乱させるだけ
445:はちみつ餃子 ◆8X2XSCHEME (ワッチョイ 423e-/YAw)
24/01/20 14:51:47.73 k6CjZuQW0.net
>>434
実際には void* と int* (などのポインタ) が同じ表現なことは多いので
あまり問題 (type punning) にならないと考えるならそうかも。
ただ、表現が同じである環境ならかまわないのかというとそうでもない。
aliasing rules が絡んでくる。
言語仕様上で適合するとされる以外の読み書きをプログラマはやらない (やったら未定義だから) という仮定の元に最適化されることがある。
>>438
ABI はその名の通りインターフェイスを一貫させるための規定であって、
外部に公開しない (外部リンケージを持たない) 部分ではコンパイラは最適化するし、オブジェクトを除去することもある。
私は >>422 で「あてにしていい環境ならそうすることは否定しない」と述べたが、
あてになる確証を得るのは割とめんどい。
言語仕様を調べて分かる範囲で済むならそうする。
少なくとも >>392 をインライン関数にするために手間をかけるなんてことはしない。
446:デフォルトの名無しさん
24/01/20 14:57:01.22 UfD1Ji0o0.net
だから、その環境が不明瞭なこういう場所で問題になるわけでしょ?
実際>>392では「処理系はANCI C準拠」としか言っていないわけだし
447:デフォルトの名無しさん
24/01/20 14:57:54.96 UfD1Ji0o0.net
おっと440は>>437-438アテネ
448:デフォルトの名無しさん (ワッチョイ 463f-ggGG)
24/01/20 15:58:08.13 QcwVnceA0.net
未定義とは規格遊びには便利な言葉だなw
正解はconfigureスクリプトがやってるように、事前に環境を調査して前提にしていい事を明確にして最適な実装をする事だな
なので、言語仕様のみで判断を下す事は不正解と言える
その為にconfigureスクリプトがある
他の言語ではあまり必要ない
Rustとか最近の言語は言語仕様に不明瞭な点は残さないのがトレンドだろう
じゃなきゃそこが脆弱性を生んでしまう
449:デフォルトの名無しさん (ワッチョイ 463f-ggGG)
24/01/20 16:03:47.86 QcwVnceA0.net
>>392のマクロは、副作用のある式を渡したりするとおかしな事が起きる
全くもって脆弱なものだ
そのままで良いのか?
マクロのままにしておくとか、そっちの方が脆弱性を生む事になる
ちゃんと関数化すべきだろ
その為にすべき事は何だ?
それを議論することが正解と言っている
450:デフォルトの名無しさん
24/01/20 16:33:16.28 7OBiWfZx0.net
副作用のある式とは例えば?
451:デフォルトの名無しさん
24/01/20 19:48:07.23 31IXtECu0.net
p++じゃない?
452:はちみつ餃子
24/01/20 19:54:12.68 k6CjZuQW0.net
関数で書いたら問題を避けられるわけ?
453:デフォルトの名無しさん (ワッチョイ 0279-5stn)
24/01/20 21:49:35.15 VgpxxxtV0.net
C言語で今更議論することなんてないよ
気に入る要らないはモダン言語とかでやってなさい
454:デフォルトの名無しさん (ワッチョイ 450a-rpIY)
24/01/20 22:17:38.62 DXZ/M+lB0.net
使用済みのポインタ変数を変なやり方でクリアするとかクソどうでもいい
455:デフォルトの名無しさん (ワッチョイ 22ec-HXAs)
24/01/20 22:21:19.13 7OBiWfZx0.net
>>445
それは考えなくていいでしょ
456:デフォルトの名無しさん (ワッチョイ 463f-ggGG)
24/01/20 22:34:47.06 QcwVnceA0.net
>>446
え?本気でいってんの?
関数で書けば副作用(例えば++p)は1回で済む
当然副作用がある式を書くのは
457:アホだと思うが、少なくとも書いた通りには動く
458:デフォルトの名無しさん (ワッチョイ 463f-ggGG)
24/01/20 22:44:54.31 QcwVnceA0.net
例えば、(uint8_t)malloc(...) + sizeof(int)を返す関数もあり得る
これは前の方にデータを隠すテクニックだ
実はC++のコンパイラで普通に使われている
これを解放する時は、free(p -= sizeof(int))とやらない事もない
まぁ普通はp - sizeof(int)だろうから屁理屈だけどねw
459:はちみつ餃子 ◆8X2XSCHEME (ワッチョイ 5f3e-3Dea)
24/01/21 00:53:03.43 4rk7TZPC0.net
>>450
解決したい問題はそれだけでいいのか。
それなら意図はわかる。
ただ現実に C の関数を多相化できないのは変えられない前提としてある。
異なる型で扱う必要があるんだから異なる関数を用意するしかないのはどうしようもなくない?
460:デフォルトの名無しさん (ワッチョイ e785-6dvo)
24/01/21 11:37:01.81 yYf7aVwb0.net
多相?
仮にポインタ変数のアドレス を引数で渡したい場合であってもvoid ** じゃなくvoid * を使って、
人間同士がドキュメントだろうが喫煙所だろうがで問題解決しろよってのが規画と整合する答えなんじゃないの
どうせキャストするんでしょうに
バカですか
461:はちみつ餃子
24/01/21 12:09:29.26 4rk7TZPC0.net
void* に変換したなら元の型にキャストしなおさないと保証された動作はほとんどない。
(逆に元の型に変換したときは変換前の値と一致することは保証される。)
元の型を知っているプログラマがキャストすることを期待できる qsort のような使い方なら問題にならないけど、
void* の形で受け取るだけでは関数が出来ることはほとんどない。
文字列を指すポインタに変換してバイト列として読み書きすることはアリなので
オブジェクトの内容はどうでもいいメモリブロック操作系の関数 (memmove など) だとかでも問題はないかな。
462:デフォルトの名無しさん
24/01/21 12:53:39.98 +eMrRol8M.net
簡単な問題だったんだけど答えられる人ほとんどいないのか
相変わらず本題とは関係ない問答しだすアホらもいるし
463:デフォルトの名無しさん
24/01/21 13:01:11.71 fu4eKftF0.net
答えられる人はいるだろうけど、宿題丸投げするやつにエサを与えたくなくて
敢えて書かない人もいるだろう。
464:デフォルトの名無しさん
24/01/21 16:35:59.78 ocg3B/5o0.net
ANCIとか頭悪そうな学校で相手したくなかった
465:デフォルトの名無しさん
24/01/21 16:43:50.02 WaBPg/nL0.net
誰も知らない新規格、か・・・
466:デフォルトの名無しさん
24/01/21 16:44:16.43 sYjtPxaw0.net
宿題スレは別にあった様な気がする
467:デフォルトの名無しさん (ワッチョイ c7df-VcUz)
24/01/21 20:09:55.64 BpmEGVkv0.net
つ スレリンク(tech板)
468:デフォルトの名無しさん (ワッチョイ 7f2a-Hmn+)
24/01/21 22:42:42.89 fOwYJqZP0.net
UNCI はどうだろう。
469:デフォルトの名無しさん (ワッチョイ 7fab-JMeY)
24/01/22 09:16:06.10 wwjNYCJK0.net
>>445
free(p++);
p++=0; ←ここで文法エラーになるから
470:デフォルトの名無しさん
24/01/22 19:23:27.59 sQG6cOu30.net
このマクロでそんな心配せんでええやろ
471:デフォルトの名無しさん (ワッチョイ 7f63-HLt9)
24/01/22 20:21:33.49 oQuCuzrM0.net
Cに引数の参照渡しってあったっけ?
ないとしたら>>392のMYFREE(p)をマクロではなく関数として書き
その中でp=0としても呼び出した側の変数は変えられないわけで
関数にすることで動作が変わってしまうことになるはずだけど
472:デフォルトの名無しさん
24/01/23 13:25:33.99 DCTvqhlA0.net
そんなこんなでp++マクロには問題が多いからC++が出来たってわけ
473:デフォルトの名無しさん
24/01/23 14:30:32.20 FpD2d5od0.net
なんだそんな理由だったのか・・・
474:デフォルトの名無しさん
24/01/23 14:41:04.92 v+doC8dF0.net
mallocとcallocの引数の指定の仕方が違うのが気になる
これ別であることに理由あるの?
475:はちみつ餃子
24/01/23 15:14:53.60 MIeJSKFF0.net
>>467
言語仕様上は calloc が返すポインタ (によって表されるメモリ領域) は
malloc が返すものと同じようにあらゆる型に対して適切に境界調整されることになっているし、
ゼロクリアするという違いも「全てのビットがゼロ」という意味なので型の性質を考慮しない。
つまりふたつの引数として指定することによって得られる恩恵はない。
実装がまともなら calloc(a, b) としたときの a*b が size_t の大きさを超えてしまうようなときでも
ラップアラウンドして小さな領域を確保するのではなくエラーにしてくれることは期待できる
(間違いを検出しやすい) が、それを理由として引数ふたつにしているというわけではなさそう。
最初に言語仕様をまとめたときに主要な処理系がだいたい準拠ということになるようにしたはずなので
その頃の処理系でなんか理由はわからんがそうなってたって程度の話だと思う。 あまり意味ない。