C++相談室 part159

■ このスレッドは過去ログ倉庫に格納されています
1デフォルトの名無しさん
垢版 |
2022/02/19(土) 11:56:42.14ID:kSnJ/KwP
前スレ
C++相談室 part158
https://mevius.5ch.net/test/read.cgi/tech/1636969758/
2022/02/19(土) 12:05:32.96ID:b+8HD1Ua
C(チンチン)+(プラ)+(プラ)
2022/02/19(土) 13:32:43.00ID:rSu4VNCf
アセンブリとかC言語だと「この操作はするな」ってのを簡単には禁止できないからね

許可されてる(コンパイラから怒られない)操作が増えるとその分だけ不正解のコードを書くリスクが高くなる

structのこのフィールドは排他制御してから変更してねってのをC言語じゃ簡単には強制できんだろ
C++ならgetter作ればいいだけなのに
2022/02/19(土) 13:38:43.35ID:2h4SA+VW
>>1
>>1000は宣言に従うこと

>>3
それぐらいはC程度の高水準言語であればギリ保証できる
クラスFooに対するgetterやsetterを経由しないアクセスを
Fooの構造体メンバ名を変えたときビルドエラーとして確実にあぶりだせる
ように書くことはFooを書く人の一存で一応できる
2022/02/19(土) 13:52:37.43ID:2h4SA+VW
カプセル化が簡単にできるというのと、
 オブジェクトC := オブジェクトA + オブジェクトB
 オブジェクトE = オブジェクトC * オブジェクトD
 ...
ここで:=は生成、+や*はなんらかのメッセージ(メソッド)
このようにオブジェクトからオブジェクトを作る、的な、
基本単位がオブジェクトなプログラミング環境が維持されないのは
オブジェクト指向プログラミングしているうちに入らないと
思うんですよねー(棒
2022/02/19(土) 15:57:04.56ID:ymxofDah
format.hを待ってますた
2022/02/19(土) 15:59:32.57ID:lVeS0ElI
>>3
でもそのC++からCを見て不正解のコードを書くリスクが高くなるという話がそのまま
RustからC++を見た場合も当てはまってしまうよな
Rustコンパイラならメモリ安全やデータ競合に問題がある操作をエラーで拒否するのにC++はなぜ許して致命的バグを生み出してしまうのだろう、と
2022/02/19(土) 17:53:08.72ID:kSnJ/KwP
無関係過ぎる
元はアセンブラ必須という人が書き込みがあったので、C++のコンパイラ(gcc)がSIMDを吐く条件についての話をしたんだが・・・
それについては正解できる人や惜しい人すら皆無で、馬鹿がC++全然関係ないOOの話を引っ張ってきて、今じゃC++と無縁な宇宙の話になっている
2022/02/19(土) 18:09:20.91ID:x/upE6G9
自分でこんなレスしといて今更何言ってるんだかw
> 組み込み機器用のCPUって特殊なんで、コンパイラが安定しないなんてよくある話
> オブジェクト指向のメリットの本質についての話なので、可能/不可能が実装言語に依存しないというのもよくある話(楽かどうかは別)
> 別に昭和でも平成でも令和でも変わってないけど、>> 991に伝わってないのは確か
2022/02/19(土) 18:26:04.31ID:kSnJ/KwP
馬鹿がID変えてまた登場
2022/02/19(土) 18:50:37.51ID:mDQ0X8WX
明示的にはSSEコンパイラ組み込み関数を使えば実現できるけど、多くのコンパイラはシングルレーンのループの一部を自動的にベクトル化してくれるのね

コンパイラが暗黙的なベクトル化をしてくれる条件ってシングルレーン以外に何があるんだろ
2022/02/19(土) 19:09:18.39ID:x/upE6G9
>>10
顔真っ赤じゃんw
2022/02/19(土) 19:43:50.83ID:kSnJ/KwP
その問題はもう答え書いた
2022/02/19(土) 20:38:46.85ID:x/upE6G9
恥の上塗りかよw
答えを書いたとか関係ないだろ
> 馬鹿がC++全然関係ないOOの話を引っ張ってきて
に乗っといて何言ってるんだよ
2022/02/19(土) 21:13:10.67ID:kSnJ/KwP
可哀想な馬鹿が勘違いしてるみたいだからちゃんと書いておくと、>>13>>11へのレスな
2022/02/19(土) 21:45:03.99ID:x/upE6G9
人をバカにしても恥ずかしいレスは消えないよw
2022/02/20(日) 02:19:28.36ID:c79emsKu
>>7
実際そうだよ
生のポインタを使ってる限りはどこに所有権があるか自分で管理するしかない

Rustの考え方はC++使いからすれば羨ましいわ
2022/02/20(日) 05:27:00.10ID:aLhaBLLn
けんかをやめて ふたりを止めて
わたしのために 争わないで
2022/02/20(日) 09:25:04.73ID:JXXbW9ML
きみC#さんだよね
2022/02/20(日) 10:18:23.47ID:c+ifp9sQ
>>17
だからスマポで出来るやん、それ
てか欧米産の大手ゲームの解析なんかしてると普通に向こうもスパゲッティコードだらけだけどな
なんだかんだで力技ゴリ押し開発になっちゃうんだよ結局
2022/02/20(日) 10:23:29.96ID:mD/m0vxj
ゲームはハード性能をゴリゴリに引き出すのが正義だからスマポ程度のオーバーヘッドでも許容できないんよ
2022/02/20(日) 10:30:30.73ID:c+ifp9sQ
>>21
いや俺もゲーム開発しとるけどスマポどころかGC任せにするのがもうここ10年くらいは主流だぞ?(最終的にはネイティブ化されるけどそれでもゼロオーバーヘッドになる訳では全くない)
2022/02/20(日) 10:31:03.74ID:hF9eBvbm
え?
ゲームでもスマートポインタは普通に使うよ
2022/02/20(日) 10:36:14.20ID:mD/m0vxj
ああ、ゲームって最新の3Dグリグリのやつな(欧米の大手って言うからそっち想像しちゃった)
スマホゲーやブラウザゲーはまた別よ
2022/02/20(日) 10:37:11.73ID:c+ifp9sQ
>>24
タルコフ見て同じ事言える?
2022/02/20(日) 10:40:48.26ID:hF9eBvbm
ID:mD/m0vxj は知ったかぶりだね
なんのためにC++相談室スレにデタラメを書き込んでるの?
27デフォルトの名無しさん
垢版 |
2022/02/20(日) 10:43:58.31ID:h6G+3sJT
共用体が良くわからないのですが、同じメモリーアドレスを複数のメンバで共用するとは
どういうことなのでしょうか?
メモリの節約と書いてあるのですが、よくわかりません。
同じ型の共用体が複数あったときに使ってないメンバ変数が勝手に消されるなんてわけないですよね
どなたか共用体と構造体の違いを教えていただければ幸いです。
(まだクラスについての知識はほとんどないです。)
2022/02/20(日) 10:51:16.26ID:lvHr33WL
PODで型変換するくらいしか使わんのでは
2022/02/20(日) 10:53:23.74ID:c+ifp9sQ
>>27
とあるデータの見方を複数用意するのが共用体
union { intptr_t integer; void* pointer; } value;
↑が構造体であればvalueはポインタ*2分のメモリを使うところ、共用体だとsizeof(value)は4(32bit)or8(64bit)って感じで変数1個でしかない
integerとpointerは実体は全く同じデータを見ていて、その見方を二つ用意しただけ
value.integer = 8;ってするとpointerも8になる
30デフォルトの名無しさん
垢版 |
2022/02/20(日) 10:55:47.01ID:h6G+3sJT
え!?メモリの節約ができるの!?
でも・・・制限があるんでしょ?
って感じで気になるのです。
ただ、基底クラスとか継承っていうのがわからないんだけど、
クラスについての記述がもう少し先にあるから、まだクラスの部分について読みたくない
、クラスを学んでから共用体について学んだほうが良いのでしょうか?
31デフォルトの名無しさん
垢版 |
2022/02/20(日) 10:56:42.82ID:h6G+3sJT
>>29
ありがとうございます今すぐ読みます
2022/02/20(日) 11:01:01.36ID:mD/m0vxj
そのレベルなら共用体なんて使わないし使うべきじゃないから読み飛ばしていいよ
一通り学習してから戻ってきな
2022/02/20(日) 11:02:54.57ID:c+ifp9sQ
>>30
別に直接的にメモリの節約が出来る訳ではない
>>29の例で言った通り、一つのデータに対して複数の名前を付けるだけの話なのでデータは結局一つしか同時には入れられない
なんか実用的な例ありそうだけどunionはC++だとそんな使わないし積極的に使うべきでもないからすぐには思い浮かばない
2022/02/20(日) 11:15:09.90ID:5KrZlkth
variantとかは中身は共用体だった気がする
2022/02/20(日) 11:16:50.11ID:uUEkIMOM
>>27
例えばスクリプト言語みたいに色んな型が入る変数を定義したい時に
struct {
char c;
int i;
double d;
};
みたいにするとdを使ってる時はc, iの領域が無駄だよね、そういう時に
union {
char c;
int i;
double d;
};
のようにすると領域が無駄にならない
36デフォルトの名無しさん
垢版 |
2022/02/20(日) 11:24:25.42ID:h6G+3sJT
なんか気になっちゃうのです。
union value { int test1; double test2; } ;
int main()
{
value test;
test.test1= 2147483647;
test.test2 = 1.4;
cout << sizeof test<<endl;
cout << test.test1 << endl << test.test2<<endl;
}
これなんですけど、共用体のサイズは8byteで構造体にすると16バイトになります。
でも、doubleって8byteですよね?
共用体valueの中には4byteのtest1と8byteのtest2があるはずなのですが、
なんで共用体valueは8byteなのでしょうか?
そもそも共用体の中に変数があると言う考え方が間違ているのでしょうか?
37デフォルトの名無しさん
垢版 |
2022/02/20(日) 11:25:50.54ID:h6G+3sJT
>>35
ありがとうございます。ちなみにその仕組みとかって・・・聞けたりとか・・・
38デフォルトの名無しさん
垢版 |
2022/02/20(日) 11:26:58.89ID:h6G+3sJT
structだと4byte無駄になるのですね。
39デフォルトの名無しさん
垢版 |
2022/02/20(日) 11:28:36.50ID:h6G+3sJT
何となくなのですが、構造体だと
メンバの中で一番大きな変数のサイズ*メンバの数
分の領域が確保されるのかな?って思ってみたりしています。
2022/02/20(日) 11:35:01.82ID:c+ifp9sQ
>>36
だから正に"共用"体という名の通り、test1とtest2はメモリの場所を共用してる
君が言う通り、intは4byte、doubleは8byte
この場合はunion全体としてのサイズは大きい方に合わさるが、メモリの場所を共用してる事には変わりないためtest2(double)の下位4バイトとtest1(int)が重なってる事になる
intとdoubleだと出力分かりづらいからunion value { int test1; long long test2; } ;でやってみ

test1 = 0x5;
test2 = 0x2410000000000007;
こうするとtest1は7(0x00000007)、test2(0x2410000000000007)はとなる(下位4byteは共用されてる)
2022/02/20(日) 11:39:14.94ID:c+ifp9sQ
>>40
これがstructだとちゃんと4+8で12byteの構造体となる(アラインメントって概念によりそうでない事もあるけどそれはまた別で勉強したほうがいい)

test1 = 0x5;
test2 = 0x2410000000000007;
structだとさっきと同じ事をしてもtest1とtest2でメモリは共用されておらずそれぞれ独立しているため、test1は0x5、test2は0x2410000000000007となる
42デフォルトの名無しさん
垢版 |
2022/02/20(日) 11:41:34.03ID:h6G+3sJT
>>40
ありがとうございます。
すごいっす、メチャすごいっす。
あまりの喜びに敬語忘れてすみません。
"共用”なのですね。
ってことは共用体はいくつかメンバ変数を用意しておいて、一個だけ使なら使ってもいいよ。
しかも、いちばん最後に代入された値が採用されるよと言うことで大丈夫でしょうか?
2022/02/20(日) 11:42:49.02ID:5KrZlkth
ポイントだけ聞くようにして全部聞こうとすんなアホ
2022/02/20(日) 11:50:02.29ID:hF9eBvbm
そもそもC++スレ
45デフォルトの名無しさん
垢版 |
2022/02/20(日) 11:52:56.02ID:h6G+3sJT
>>40
おかげさまで何とか理解できました。
自分の書いた上の記述(>>41)もちょっと違ってたような気がするけど
まぁ置いておいて・・・。
本当にありがとうございます。
2022/02/20(日) 11:53:19.65ID:lvHr33WL
共用体とビットフィールドでウハウハよ
2022/02/20(日) 12:26:21.52ID:8UrVWzFH
>>20
スマートポインタを徹底すればできるが記述量が結構増えるのよ
結局面倒臭くなって使わなくなってしまった
2022/02/20(日) 12:30:45.48ID:8UrVWzFH
共用体はデータ量をケチる目的では使わんでしょ
(マイコンとかバイナリデータとかの)データの配置順に意味があるやつとの相互運用にしか使ったことないぞ

union A{
struct{ char low; char high;};
short data;
};

union B{
struct { int head; double body;};
char data[12];
};
2022/02/20(日) 12:31:01.23ID:VFmEI3Uz
スマポは使えば楽できるときと
そうでないときがあるからな
見境のないスマポ厨はただのマゾ
2022/02/20(日) 12:38:44.84ID:BLiyeQro
>>48
大量に確保するデータの場合1バイト2バイトが大きく影響することもあるから、データ量目的でも使うよ
2022/02/20(日) 12:38:51.77ID:5nwqcAs1
参照オブジェクトを処理するのに
何故か内部でスマポ使いだしたとしたら
予めそいつの代わりに謝っておいてやろう。スマポ。
2022/02/20(日) 12:40:31.26ID:5KrZlkth
共用体は特定のアーキテクチャで上位下位とか分けるのに使うのが多かったけど、上に書いたようにstd::variantで使うので主にメモリ節約だと思う

ところで↓でコメントにしてるエラーはなんか悔しくない?どうしてこういう仕様なんだろう?
#include <iostream>
using namespace std;
struct s {
int a;
};
int main() {
s o;
cout << sizeof(o.a) << endl;
cout << typeid(o.a).name() << endl;
cout << sizeof(int) << endl;
cout << typeid(int).name() << endl;
cout << sizeof(s::a) << endl;
//cout << typeid(s::a).name() << endl; // error
return 0;
}
2022/02/20(日) 12:44:49.03ID:BLiyeQro
sjis/utf8、utf16、utf32を一緒くたに扱う文字列クラスを作った時にそれぞれの型のポインタを共用体で持たせたな
キャストするより楽だったからw
2022/02/20(日) 12:49:58.81ID:EDNjM2Vr
>>48
それはお前の経験が足らんだけ
>>34が言うようなケースでも使うよ
2022/02/20(日) 13:44:10.67ID:MjuaBSm2
>>51
これ何であかんの?
2022/02/20(日) 13:59:07.64ID:uAn4231w
>>36
アセンブラでアライン覚えて来い青二才
2022/02/20(日) 15:04:19.29ID:aLhaBLLn
共用体使うとシフト演算しなくていいし、
最近のCPU(っても20年まえぐらい)から1ビット操作命令もあるし、パフォーマンスがいいと思うぜ
2022/02/20(日) 18:12:12.24ID:8IAIbIwN
>>54
std::variant見てきた
ただのunionラップクラスじゃねーか
2022/02/20(日) 19:01:05.55ID:uUEkIMOM
>>58
> ただのunionラップクラスじゃねーか
それの何が不満なんだよw
2022/02/20(日) 21:42:58.02ID:8IAIbIwN
ただのunionラッパーをunionの活用例かのような言い方をした >>54 に対する不満だ
2022/02/20(日) 21:47:59.16ID:uAn4231w
米大統領と密談した「IQ1200の金星人」ヴァリアント・ソーとは ...
2022/02/20(日) 22:02:46.59ID:uUEkIMOM
>>60
意味わからんw
ラッパーだと活用例じゃないとでも?
2022/02/20(日) 22:37:27.22ID:V67/tnWS
スマポの記述量が長い問題って皆どうしてんの?
2022/02/20(日) 22:52:41.23ID:uSEnVnLU
C++のstd::variantとほぼ近い、
Rustのenum(=格納付きenum=タグ付きunion)を比べると
圧倒的にRustのenumが使いやすくてRust言語の核心部分となっていることからもわかるように
C++ではその分野の言語サポートが弱いんだよな
2022/02/20(日) 22:54:00.38ID:uSEnVnLU
>>63
その件もRustが上手いことやってるよな
2022/02/20(日) 23:01:58.00ID:V67/tnWS
>>65
そうなのか
正直あんまり触ったことないんだが、そういう話なら触ってみようかな
2022/02/20(日) 23:24:26.58ID:5KrZlkth
Rustのことはスレ違いだけど、言語機能としてどこまでサポートするかは、分かりやすさと直結してると思う
C++のstd::variantの方が分かりやすいと思う人もいれば
Rustのenumの方が分かりやすいと思う人もいると思う
■ このスレッドは過去ログ倉庫に格納されています
5ちゃんねるの広告が気に入らない場合は、こちらをクリックしてください。

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