C++相談室 part149

■ このスレッドは過去ログ倉庫に格納されています
1デフォルトの名無しさん
垢版 |
2020/02/18(火) 06:19:41.54ID:xvjipUWj
C++に関する質問やら話題やらはこちらへどうぞ。
ただし質問の前にはFAQに一通り目を通してください。
IDE (VC++など)などの使い方の質問はその開発環境のスレにお願いします。

前スレ
C++相談室 part148
https://mevius.5ch.net/test/read.cgi/tech/1580471646/
このスレもよろしくね。
【初心者歓迎】C/C++室 Ver.105【環境依存OK】
http://mevius.5ch.net/test/read.cgi/tech/1556142878/

■長いソースを貼るときはここへ。■
 http://codepad.org/
 https://ideone.com/

[C++ FAQ]
https://isocpp.org/wiki/faq/
http://www.bohyoh.com/CandCPP/FAQ/ (日本語)
2020/03/01(日) 12:18:16.41ID:7BIH7/M6
それでいいよ
ちなみにmemcpyの呼び出しコストは最適化で消えるから気にしなくていいよ
(コンパイラ依存だけど)
2020/03/01(日) 12:22:08.16ID:0F9Oehpq
>>377
ありがとうございます。
2020/03/01(日) 12:42:53.26ID:0F9Oehpq
追加で質問があります。

http://codepad.org/uN82gnco

この30〜31行目でemplace_back()、back()を使っているのですが
emplace_backを使うときはこうやって使うのであってるのでしょうか?

あと、上記をコンパイルすると下記エラーが出ます。

「エラー: オブジェクト以外がメンバ関数 ‘int Self::xxx(ITEM)’ を呼び出すことは出来ません」

今色々調べているのですが、何が悪くてどのように解決すれば良いかがまだわかりません。
どうすればよいかわかりますでしょうか?
2020/03/01(日) 12:44:04.60ID:GdO9iGlh
>cppreferenceを含めてネットでは std::vector ばかり使われているのは、大部分のプログラマがポインタを理解できないのでリンクリストも理解出来ておらず、使いこなすことが出来ないためと踏んでいる。
よくこんな頭の悪いこと思いつくよなw
2020/03/01(日) 12:47:43.45ID:PLnmvtRY
How can you be so certain?
2020/03/01(日) 13:00:27.97ID:2UJE7A6V
Self::xxxをSelfの後に書かないと。
ラムダ内部は別の関数だからthisにはアクセスできない。[&]を使うとか工夫しないと。
2020/03/01(日) 13:19:18.30ID:7BIH7/M6
>>379
emplaceを試したいならまずは余計なものいれずにやるべきだね

struct ITEM {
  ITEM(const char* p) : name(p) {}
  std::string name;
};

std::vector<ITEM> items;
items.emplace_back("ABCD");
for (auto& item : items) {
  printf("FF %s\n", item.name.c_str());
}
2020/03/01(日) 13:44:18.34ID:0F9Oehpq
>>382
"&"を使うということは構造体をポインタ渡しするということでしょうか?
下記でポインタ渡しにしたつもりですが、同じようなメッセージが出ました。
ポインタ渡しのことではないのでしょうか?

http://codepad.org/L0oOc9RF

ほぼ同じエラー →「エラー: オブジェクト以外がメンバ関数 ‘int Self::xxx(ITEM*)’ を呼び出すことは出来ません」

>>383
サンプルありがとうございます。
emplace_back()の時に直接引数に入れることができるんですね。
参考にさせていただきます。
クラス関数に構造体を渡すとエラーになったので、その質問をしたついでにemplace_back()の使い方の質問もさせていただきました。
2020/03/01(日) 13:50:29.27ID:7BIH7/M6
>>384
> emplace_back()の時に直接引数に入れることができるんですね。

それをやりたいからこそのemplaceだよ
無駄を省きたい上級者用って感じだね
まずは自分でITEMを作ってpush_backで追加するのが基本だと思うよ
2020/03/01(日) 13:52:07.36ID:cF4UfbiQ
違う違う、[](ITEM& item) を[&](ITEM& item)にしろってこと
2020/03/01(日) 14:10:29.25ID:0F9Oehpq
>>385
emplace_backは新しい文法でpush_backの方が従来のもののようですね。

>>386
その対応でエラーが消えました。
[&]が何してるのかまだ理解できていないので調べてみようと思います。
ありがとうございました。
2020/03/01(日) 14:23:08.70ID:cF4UfbiQ
あっと、[&](ITEM& item)より[this](ITEM& item)のほうがよかったか
2020/03/01(日) 15:44:10.68ID:0F9Oehpq
>>388
thisでもいけました。
数値のmemcpyを教えていただいた >>374 の件ですが、下記で確認するとバイト単位で逆になりました。
エンディアンの影響だと思いますが、unsigned charに反転せずに簡単にセットする方法はなにかありますでしょうか?

unsigned short num = 258;
unsigned char temp[2];
memcpy(temp, &num, 2);

printf("A %04X\n", num);
printf("B %02X%02X\n", temp[0], temp[1]);

下記結果になる。

A 0102
B 0201
2020/03/01(日) 16:31:11.59ID:7BIH7/M6
>>389
調子にのりすぎ
原因わかってんなら自分で解決できるだろ
頭使え
2020/03/01(日) 16:36:04.92ID:0F9Oehpq
>>390

すみません。
センスないような気がしますが下記で入れ替えようと思います。

unsigned char temp1[2];
unsigned char temp2[2];
memcpy(temp1, &num, 2);
temp2[0] = temp1[1];
temp2[1] = temp1[0];
2020/03/01(日) 17:16:47.98ID:ZpGOlbch
>>391
htons を使えばいいんじゃね?
言語仕様にあるわけじゃないけど、 POSIX と Windows で使えるからまあおおよそポータブルでしょ。
2020/03/01(日) 18:19:09.36ID:JrOSOdLx
>>391
素直に
temp[0] = (num >> 8) & 0xff;
temp[1] = (num >> 0) & 0xff;
でよくね?
2020/03/01(日) 18:30:07.18ID:wjTinnpB
C++の初心者質問スレってなかったっけ
2020/03/01(日) 18:38:25.85ID:3018fiZA
>>372
コピーも何も必要なくて、
uint64_t a;
BYTE *ptr = (BYTE *)&a;
ptr[0] : 0 バイト目
ptr[1] : 1 バイト目
・・・
ptr[7] : 7 バイト目
でいける。
2020/03/01(日) 18:41:25.44ID:3018fiZA
>>395
さらに、
union UUU {
uint64_t  m_u64;
BYTE   m_b[8];
};
uint64_t  a;   // 入力値
UUU  u;
u.m_u64 = a;
とすれば、
u.m_b[0] // 0 バイト目
・・・
u.m_b[7] // 7 バイト目
となる。
2020/03/01(日) 19:07:30.68ID:7BIH7/M6
>>396
それc++ではUBだよ
あれ君って天才君だっけ?
2020/03/01(日) 21:11:13.32ID:ZpGOlbch
汎用的に作るならこんな感じかな?

#include <type_traits>

template<class T>
typename std::enable_if<std::is_integral<T>::value && std::is_unsigned<T>::value, void>::type
integral_to_bytes(T n, std::uint8_t* dest) {
for(std::size_t i=sizeof(n)-1; i<sizeof(n); i--, n/=256) dest[i] = n%256;
}
2020/03/01(日) 21:22:32.67ID:qtVJ0qYe
std::array<uint8_t, sizeof(T)>を返す方が親切だぞ
2020/03/01(日) 21:50:36.45ID:ZpGOlbch
>>399
なるほど。
整数型の大きさだからそれほど大きくなることは心配しなくていいもんな。
2020/03/01(日) 22:10:49.73ID:WtPaEung
OMP_STACKSIZEが小さいとセグフォるが1Gとか指定してもいいんか?
2020/03/02(月) 01:26:05.82ID:jXMtMdaQ
>>397
UBという証拠は?
2020/03/02(月) 01:46:27.25ID:jXMtMdaQ
>>397
少なくともちゃんと例としては使われている:
https://aticleworld.com/little-and-big-endian-importance/
2020/03/02(月) 01:47:31.58ID:jXMtMdaQ
>>403
typedef union
{
uint32_t u32RawData;
uint8_t au8DataBuff[4];
} RawData;
uint32_t ChangeEndianness(uint32_t u32Value)
{
RawData uChangeData,uOrginalData;
uOrginalData.u32RawData = u32Value;
//change the value
uChangeData.au8DataBuff[0] = uOrginalData.au8DataBuff[3];
uChangeData.au8DataBuff[1] = uOrginalData.au8DataBuff[2];
uChangeData.au8DataBuff[2] = uOrginalData.au8DataBuff[1];
uChangeData.au8DataBuff[3] = uOrginalData.au8DataBuff[0];
return (uChangeData.u32RawData);
}
2020/03/02(月) 02:13:31.73ID:jXMtMdaQ
C/C++では高速化のためCPUのマシン・アーキテクチャをそのまま使う。
マシン・アーキテクチャによって little endian と big endian の違いが有るのでC++言語仕様としては定義されてないが、「but most compilers define」なっている。
これはつまり、littele endian の CPUなら、そのまま little endian での表現がそのまま読みとられ、big endian の CPUなら、そのまま big endian での表現がそのまま読み取られることを意味している。
たとえば、cppreference では、
「reading from n or c is UB but most compilers define it」
となっており、
32BIT値の 0x12345678の場合に、unionで 16BIT 配列の0要素目に0x0011を代入すると、
0x12340011 or 0x00115678
が読み取られるように書いてある。
undefined behaviour であっても、このどちらかに限定されると言うことであろう。

https://en.cppreference.com/w/cpp/language/union

union S
{
  std::int32_t n;   // occupies 4 bytes
  std::uint16_t s[2]; // occupies 4 bytes
  std::uint8_t c;   // occupies 1 byte
};           // the whole union occupies 4 bytes

int main()
{
  S s = {0x12345678}; // initializes the first member, s.n is now the active member
  // at this point, reading from s.s or s.c is undefined behavior
  std::cout << std::hex << "s.n = " << s.n << '\n';
  s.s[0] = 0x0011; // s.s is now the active member
  // at this point, reading from n or c is UB but most compilers define it
  std::cout << "s.c is now " << +s.c << '\n' // 11 or 00, depending on platform
       << "s.n is now " << s.n << '\n'; // 12340011 or 00115678
}
406デフォルトの名無しさん
垢版 |
2020/03/02(月) 04:24:33.89ID:hM5tZRlI
先月ぼくが通った道だけど、結論が全く違ってて興味深い。
2020/03/02(月) 08:40:39.81ID:vdXXyaaZ
UBの恐ろしさを知らない子の結論だね
若いなあ
2020/03/02(月) 08:56:34.60ID:/NXxliI7
老害なのか子なのかどっちかにしろ
2020/03/02(月) 09:31:30.94ID:TcdIMkwU
>>403
cではOKなんだよ
だからわざわざc++ではって限定したんだから察せよ
cでは定義されてるから多くのコンパイラーはc++でも同様の解釈する
また実際のところ今後ずっとそうだろう(今回のケースに限っては)
でもUBはUB
屁理屈つけて自己正当化しようともそれは変わらない
エンディアンでなくライフタイムの問題でしょ、c++の常識的に
2020/03/02(月) 09:37:25.38ID:x4CDu4GY
くっそしょーもねえ
2020/03/02(月) 10:51:20.25ID:4ZdkwDZZ
>>405
ほとんどの場合に大丈夫だろうという見立ては間違ってないと私も思う。
で、大丈夫でなかったときは?
たぶんコンパイルエラーにも警告にもなることなく黙って未定義動作に突入する。

各処理系・環境での挙動が保証されている (検証が済んでいる) なら別に使ってもいいんじゃないのとは思うけど、
union を使ってすごく良くなるというわけでもないので、あえてやることもないんじゃないのとも思う。
少なくとも最初は選択肢から外すなぁ。
2020/03/02(月) 13:35:46.29ID:kyrXnWYL
本人わかってんだからそんな必死になって噛み付くようなことでもないだろ
だいたいプラットフォーム全く限定せずにC++でソフトが書けるのかと

>>411
>たぶんコンパイルエラーにも警告にもなることなく黙って未定義動作に突入する。
アホか
普段警告レベル下げてるから気付かねーんだよ
2020/03/02(月) 15:19:49.70ID:AN3bmLPv
v
2020/03/02(月) 15:20:44.34ID:AN3bmLPv
(↑のv はミスしました)
>>409 >>411
実は、union より、>>395 のように単純に書いたほうが良い。
unionの場合は、最初に代入によるコピー動作が入るが、>>395 は、単に 64bit 整数の入っている変数のアドレスを取得しているだけだから、全くコピー動作が入らず、物凄く効率が良いし、未定義動作でもない。
>>395 が未定義動作というなら、Cの根幹が揺るぐ。
2020/03/02(月) 15:23:49.36ID:AN3bmLPv
>>409
little endian と big endian の違いだけで全面的にUBということではないはず。
unionの仕様からいえば、ちゃんと 64BIT 整数をそのままイメージとして投影したものがバイト配列になって取得できるはず。
それがunionの定義なのだから。
sizeof(union型)とsizeof(unionのメンバ)の関係も定義されているので、それ以外の実装は有り得ないはず。
2020/03/02(月) 15:28:47.95ID:LGtCkZFK
>>415
お前は人のレスよく読め
cの話はしてないんだよ
2020/03/02(月) 15:43:11.75ID:x4CDu4GY
private/protectedで隠されているわけでもないPODの
ビット表現に依存するなってのは理に適わない
規格が保証しないなら自己責任というだけの話
そんなんどこにでもいくらでもある
418デフォルトの名無しさん
垢版 |
2020/03/02(月) 16:18:13.98ID:x4CDu4GY
test
2020/03/02(月) 16:23:29.71ID:AN3bmLPv
>>416
>>396 で言えば、m_u64, m_b メンバの先頭アドレスがどちらも offset 0 から始まっている限り、little endian と big endian の違いを除いては、どんな処理系でも、m_64 のメモリ中での表現がそのままバイト配列 m_b[] に投影されて読み出せる。
それがunionの定義。
メンバがすべて「offset 0」に配置されるかは、アラインだけの問題。
2020/03/02(月) 16:39:58.55ID:4ZdkwDZZ
>>415
規格では全面的に UB だよ。
C++11 の 9.5 を確認してみたんだけど、
共用体で保証されているのは

- 直近で入れたのと同じメンバで取りだす場合
- 先頭部分に共通する型を持つ標準レイアウトの型をメンバとして持つ共用体であれば共通部分を使うのはアリ (← 言い回しがややこしくてスマン)

ってことだけで、あくまでも先頭に適合する型が連続する部分に限って許してる。
そんでもってこれは規格の書き方はちょっと違うだけで C でも同じだわ。
2020/03/02(月) 16:44:13.99ID:LGtCkZFK
>>419
自称天才さんですらUBであることは認めてんのにお前ときたらw
まぁ後は好きにどうぞ
422デフォルトの名無しさん
垢版 |
2020/03/02(月) 16:57:58.17ID:N0Zwryo+
コンピュータはチューリングマシンではない!!!

理由 ---- timeGetTime();

マザボの時計は計算不可能的だ、時計を計算できる「アルゴリズム」は存在しない

理由2 multi-thread チューリングマシンはシングルスレッド的だ
理由3 multi-process シングルスレッドで並列計算を真似る
―― つまり、チューリングマシンなる理論自体はそもそも間違っている!
なぜなら単一のチューリングマシンは並列計算を真似ることができる
つまり、チューリングマシン自体は矛盾している!
(たとえば p->Update(); q->Update(); これはシングルスレッドのコードだ、
つまり、単一のチューリングマシンだ、しかし実行時の効果は並列的だ!)
2020/03/02(月) 17:05:20.01ID:x4CDu4GY
char配列とunionにしてバイトアクセスなんて
みんな自己責任でやってるに決まってるだろうが

そこへ、その案件の関係者でない者が頼まれもしないのにしゃしゃり出て
「UBだ」とキリるのが格好いいと思っているのはそいつ自身だけだ
2020/03/02(月) 17:40:48.54ID:/apuYuUB
>>423
分かってる奴が自己責任でやってるだけなら誰も止めないよ。
今回の場合、初心者の質問(>>389)に対し自称上級者がunionを使う方法(>>396)を提示したから、それはUBだと突っ込まれたんだろ。
別にUBを指摘することがカッコ良い訳ではないけど、指摘されて真っ赤になることはカッコ悪いぞw
2020/03/02(月) 17:44:58.26ID:x4CDu4GY
ああ、=にしたいわけね
いいよ別に
こっちも証明できねえし

ただ、おまえさんのアドバイスは俺の胸には全く響いていない
その事実が変わらん限り痛くも痒くもない
2020/03/02(月) 17:45:42.25ID:AN3bmLPv
>>420
しかし、メンバのアラインの問題さえクリアしていれば、union中の2つのメンバの
offset address は 共に0になる。
そして、以下の通りなので、メモリ中の同じアドレスから読み書きすることになるので、C++の仕様に明示されていなくても、m_b[k] の動作は単純に、m_u64のメモリ中のイメージをそのまま先頭から読み書きすることになる。
なので、問題が起きるとすれば m_u64 と m_b のアラインの問題のみだ。
もし、アラインが合わなかった場合には、m_b[k] が k == 0 でも、m_u64 の途中のアドレスから読み出すことになったりする事になる。
しかし、この様な場合に m_u64 と m_b のアラインが合わない処理系は多分、珍しい。

union UUU {
  uint64_t m_u64;
  BYTE   m_b[8];
};
UUU xx;

xx.m_u64 // もうこの段階で、コンパイラ内部では m_u64 が元々 union のメンバであったという情報は消えることになることが C/C++ の仕様では保障されている。。
xx.m_b[k] // もうこの段階で、コンパイラ内部では m_b が元々 union のメンバであったという情報は消えることになることが C/C++ の仕様では保障されている。。
2020/03/02(月) 17:47:34.63ID:LGtCkZFK
>>423
自己責任とかじゃねーっての
cでは合法的なtype punning
お前strict aliasing理解してるか?
2020/03/02(月) 17:53:08.73ID:vdXXyaaZ
やっぱりUBの怖さ全然わかってない子か
おっしゃる通りオフセットのアドレスはたまたま一緒かもしれないし、規格を読み解けば論理的にそうなるべきであることは導けるのかもしれない
だけどそれが何だというのか?
そのオフセット値から読み取ってくれることや、そもそも読み取り動作をしてくれるとどうして言い切れる?
未定義動作ではコンパイラが何をするのも何をしないのも完全に自由だということをお忘れなく
2020/03/02(月) 17:53:41.95ID:AN3bmLPv
https://stackoverflow.com/questions/25664848/unions-and-type-punning

4. THE SAFE CASE: unsigned char

The only safe manner of using type punning is with unsigned char or well unsigned char arrays (because we know that members of array objects are strictly contiguous and there is not any padding bytes when their size is computed with sizeof()).

 union {
   TYPE data;
   unsigned char type_punning[sizeof(TYPE)];
 } xx; 
Since we know that unsigned char is represented in strict binary form, without padding bits, the type punning can be used here to take a look to the binary represention of the member data.
This tool can be used to analyze how values of a given type are represented, in a particular implementation.

I am not able to see another safe and useful application of type punning under the standard specifications.
2020/03/02(月) 17:55:17.52ID:x4CDu4GY
>>427
いーや自己責任だ
おまえさんが知らないだけ

どの案件の関係者でもなさそうだな
2020/03/02(月) 17:56:57.42ID:vdXXyaaZ
>>429
その回答の下に「Cだけだろ」ってツッコミ入ってるだろ
このあわてんぼうさんめ
2020/03/02(月) 18:18:40.49ID:LGtCkZFK
>>430
何を根拠もなく断言しとんねんこの老害
cppreferenceはっとく
これ基本的に規格に書かれてる文と同じだ
かつこれはcにしか書かれてない
c++のは下にリンクあるから読んどけ

ttps://ja.cppreference.com/w/c/language/union
共用体の内容をアクセスするために使用されるメンバが、値を格納するために最後に使用されたメンバと同じでない場合は、格納された値のオブジェクト表現が新しい型のオブジェクト表現として再解釈されます (型のパンニングと言います)。
2020/03/02(月) 18:26:04.80ID:4ZdkwDZZ
>>426
メモリのレイアウトの話だけならそれ以外の選択肢は実質的にないだろってのはわかるよ。
そりゃそうだ。
実質的にそうだってのは今さら言わなくても知ってる。

いまどきの C++ コンパイラは未定義の挙動はどうなってもいいことを前提にした最適化をすることがあるんだよ……。
去年には LLVM が const 変数への代入を削除するってのでニュースになっただろ。
https://developers.srad.jp/story/19/09/27/1626210/
const 変数は変更されない。 それが前提なんだから変更されても知らんってわけ。

今まで緩く対応してたのが厳しくなることだってある。
共用体が使われる場面ってのはメモリのレイアウトを利用したい場合ってのは多いから
現実には急に挙動を変えるなんてことはないと思うけど、
未定義を警戒するのは最適化に対する警戒なんだよ。
2020/03/02(月) 18:29:44.89ID:EH9ZG6fb
このスレみててなんとなく餃子くいたくなったからスーパーいったけど
売りきれてたわ
2020/03/02(月) 18:33:24.10ID:AN3bmLPv
>>432
次も非常に重要:
「共用体へのポインタは、そのいずれのメンバへのポインタにもキャストできます (共用体がビットフィールドを持つ場合は、共用体へのポインタはそのビットフィールドのベースとなる型へのポインタにキャストできます)。
同様に、共用体のいずれのメンバへのポインタも、囲っている共用体へのポインタにキャストできます。」

これは、union においては、全てのメンバの先頭アドレスが、すべてoffset 0から始まることが保障されていることを意味する。

なので、>>426のアラインの心配はない事になる。
2020/03/02(月) 18:34:36.46ID:AN3bmLPv
>>435
もとい。良く考えてみるとそうでもなかった。
unionへ、または、unionから cast する際にコンパイラが何らかの offset 値を足したり引いたりする可能性があるため。
2020/03/02(月) 18:52:26.82ID:x4CDu4GY
>>432
もう一度言う
どの案件の関係者でもなさそうだな
2020/03/02(月) 19:05:25.24ID:4ZdkwDZZ
>>437
おっ。 立場を持ち出すのか?
理屈では反論する余地がないという意味?
2020/03/02(月) 19:19:56.44ID:x4CDu4GY
お? =ってことでいいのか?
ID変えるとか超しょーもねーねらーだなw
2020/03/02(月) 19:29:50.21ID:4ZdkwDZZ
>>439
俺は煽ってるだけだよ。
2020/03/02(月) 19:31:34.34ID:AN3bmLPv
>>433
「const 変数を cast してから代入する」というのはそもそも元々禁止事項だから、今回の話とはかなり違う。
2020/03/02(月) 19:35:17.26ID:4ZdkwDZZ
>>441
禁止と未定義の間に差があるという誤解?
2020/03/02(月) 19:39:18.04ID:ael5BwwH
>>407, >>438
こいつらすごい嬉しそう
こういうのでしか偉そうに出来ないんだろうなぁ
2020/03/02(月) 19:39:59.11ID:AN3bmLPv
>>445
>>442 には、以下の用になっている:
// at this point, reading from n or c is UB but most compilers define it
  std::cout << "s.c is now " << +s.c << '\n' // 11 or 00, depending on platform
       << "s.n is now " << s.n << '\n'; // 12340011 or 00115678

「 11 or 00, depending on platform」
「12340011 or 00115678」

数学的に
A or B
ということは、A または Bに限られると言うことで、それ以外の可能性がないことである。
2020/03/02(月) 19:53:14.29ID:ael5BwwH
いや、さすがにそれは「大抵のコンパイラはどちらかに定義する」だから
そうじゃないのも有り得る

ただそんな変な環境まで想定するのも非現実的だし
それを言うなら1byte=8bitsとも限らないんで、そんな環境だとuint8_tもおそらく定義されておらず
はちみつがドヤ顔で自称汎用的だと挙げた>>398も使えないわけだが
2020/03/02(月) 19:58:23.59ID:4ZdkwDZZ
>>444
それだったら UB という語を使うのがおかしいよ。
C++ (の仕様) 的には UB ってのは正しいプログラムには存在してはいけないものだ。
どちらになるのか不定という意味では普通は使わない。

11 or 00 は most compilers define it に対応してるとも解釈するのが自然だと思うよ。

>>445
せやな。
そこを言うと汎用的とは言えないな。
unsigned char で定義した方が確実だったか……。
2020/03/02(月) 20:14:13.91ID:4ZdkwDZZ
C++20 では負数は2の補数形式で定義されることになったみたい。
C++ の最新規格に追従しているコンパイラは全部 2 の補数を前提にしてたからもう 1 の補数はええやろみたいな話を聞いた。

そこまで決めるのになんで1バイトの大きさは明記しないんだろ。
1 バイトが 8 ビットじゃないアーキテクチャ (で主要 C++ コンパイラがサポートしている環境) が有るんかね?
2020/03/02(月) 20:17:54.52ID:4ZdkwDZZ
>>445
十分に汎用的とは言えないけど使えないときはコンパイルエラーになるだろうから比較的マシということで勘弁。
2020/03/02(月) 20:24:42.94ID:x4CDu4GY
>>440
超しょーもねーねらー認めやがったw
2020/03/02(月) 20:26:39.31ID:LGtCkZFK
>>447
signedのwrap aroundは定義された?
2020/03/02(月) 20:37:53.23ID:4ZdkwDZZ
>>449
ID 変えとかはしてないからね。
いまどき匿名プロキシとかあんまりないし。
俺がトリップを付けないのはつまらない質問するときだけ!
(つまらないこと聞くの恥ずかしいじゃん……///)
2020/03/02(月) 20:40:00.58ID:x4CDu4GY
>>451
人のことを=っといて虫のいいことを言うな
人間としてどうなのか疑っちまうぜ
2020/03/02(月) 20:41:39.08ID:LGtCkZFK
敗走したのにもどってくんなよ
2020/03/02(月) 20:45:07.72ID:4ZdkwDZZ
>>450
されてない。 それは従来通り。
何故なのか……。
2020/03/02(月) 21:47:32.89ID:j/GXcJfE
【ソフト名】リソーエディタ
【URL】https://github.com/katahiromz/RisohEditor
【説明】リソースデータを編集できるソフト。

これ、VS2012でビルドしたら、バイナリサイズが10MB超えてるだけど、なんとか6MB以内に縮小できないだろうか?

インラインとか関係ある?
2020/03/02(月) 22:01:25.31ID:4ZdkwDZZ
>>455
デバッグ情報は取り除いてそのサイズ?
サイズだけが重要なら UPX とか使えばいいんでね。
2020/03/02(月) 22:10:19.07ID:JxKPpJ6p
>>456
うん。zip圧縮したサイズがだいたい10MB。UPXも試したけど圧縮後のサイズには効果が薄いみたい。インライン関数がデカいのがまずいのかな?
2020/03/02(月) 22:31:49.40ID:TcdIMkwU
>>457
サイズ優先の最適化オプション試してみたら
2020/03/02(月) 23:45:22.71ID:4PGofnEL
そもそも >>398 って、割り算と剰余まで使っていて、実用的なコードとは
言いがたい。
せめて、x >>=8 と x & 255 ならまだましだが、そもそも >>395
で十分なのに、敢えて複雑にして、逆にバグが入る可能性も高い。
それと、厳密に言えば、誰かも指摘したように unsigned char が 8bit かどうか
も C や C++ の仕様としては決まってないようだし。
2020/03/02(月) 23:53:18.90ID:4PGofnEL
>>398
それはバイトの概念を直接扱えないような言語でも使えると言えば使えるかもしれないが、敢えてそんなコードを書く必要はない。
「高級アセンブラ」の名が無く。

自分が知らない処理系に誰かがコンパイルすることを想定していて不安が残る場合には、どこかに
テストコードを書いておけばいい。例えば、次のようにする:
uint32_t a = 0x11223344;
uint8_t *ptr = (uint8_t *)&a;
if ( ptr[0] == 0x44 && ptr[1] == 0x33 && ptr[2] == 0x22 && ptr[3] == 0x11 ) {
 // リトルエンディアン
}
else if ( ptr[0] == 0x11 && ptr[1] == 0x22 && ptr[2] == 0x33 && ptr[3] == 0x44 ) {
  // ビッグエンディアン
}
else {
 // エラー
}
2020/03/03(火) 00:10:54.51ID:alJFGTdC
ちなみにC++20からエンディアンも標準に入る

https://cpprefjp.github.io/reference/bit/endian.html

使えるかは知らない...
2020/03/03(火) 01:43:26.11ID:vE1VkH8+
CではOK、C++ではUB
C/C++コンパイラではたまたま動く場合が多いかもしれないけど、UBはUBなんだし回避方法もあるんだからやめとこう
ただこれだけの話なんだけど

何が気に食わないのか「わかりやすいんだ!汎用的なんだ!Cらしいんだ!俺のコンパイラでは動くんだ!この程度のテクニックも知らんのか!」
ってノリでナイーブにUB書きたがる奴が絶えないのはなんでだろうね
一度でもそういうのが引き起こす地獄みたいなバグに付き合わされたら二度とそんなことしないしさせないって思うもんなんだけどね
幸運にも遭遇したことがないのか、全部他人に解決してもらってるいい身分の人なのか
2020/03/03(火) 02:22:47.77ID:V4J60F8x
> やめとこう

何の権利で指図するんだよ
2020/03/03(火) 02:40:53.66ID:vE1VkH8+
「そんなにお酒飲み過ぎると健康に悪いよ、やめとこう?」
「一生酒を飲むなと命令するのか!何の権利で指図するんだ!」

おおめんどくさい
ただのアドバイスを命令や強要や脅迫に感じるのは鬱の初期症状だから気を付けなよ
2020/03/03(火) 03:15:03.15ID:V4J60F8x
お節介なやつは人からそう見られてるんだよ
2020/03/03(火) 03:39:42.34ID:vE1VkH8+
お節介じゃないよ
俺の関係者がここを見てここのバカに勇気付けられてUB書き散らかすようになると俺が困るから言ってるんだよ
俺のためだ
2020/03/03(火) 03:54:38.06ID:V4J60F8x
逆もしかりだ
チームに入ったばかりの新入りが「UBだ! UBだ!」と喚きだし
「おまえならどうする?」に答えられないゴミには諦めてもらうしかない
どうせunion使わないためにポインタのキャストとかだろくっだらねえ
2020/03/03(火) 04:29:39.93ID:vE1VkH8+
新入りに危険な書き方を指摘されたら「くっだらねえ」と逆ギレした上に
チームで規格を当たって検討もせずに新入りに解決策を丸投げするのか
最低だなお前
2020/03/03(火) 05:43:51.35ID:WsWEE8rZ
>>459-460
まともなコンパイラはビット演算に置き換える最適化が入ることが期待できるんだから、
割り算が実用的でないなんてことはないよ。
エンディアンの影響を避けるには良い選択のひとつだ。
2020/03/03(火) 06:03:20.43ID:WsWEE8rZ
ガチで組み込み環境のシビアなやつだとバイナリのテストの方に時間をかけたりするから
逆に言語に無頓着になる場合があるというのは聞いたことは有る。

1998 年頃の自動車制御とか携帯電話とかの話なんで、
コンパイラの規格準拠具合もそれほどあてにできなかった時代の話だけど。
2020/03/03(火) 06:14:57.83ID:jgFG2YH5
数年前に触ったdspは1byte32bitだったなー
2020/03/03(火) 06:36:20.05ID:WsWEE8rZ
>>455
実行ファイル本体はさほど大きくないじゃん。
一番大きいのは cc1.exe か……。
これって必要?
2020/03/03(火) 06:43:09.65ID:0/2hhSYY
>>468
例えばmemcpyの各プラットフォームごとに向けた最適化(の元のソース)はお前がここで言うようなUBだらけだろうし
boostなんかも各プラットフォーム向けに分けて書かれてる部分が多い
そこまでUBを避けてどんなプラットフォームでも動くように、なんてのもYAGNIの一種だと思うけどね
2020/03/03(火) 06:46:29.83ID:AJx5UoX4
>>470
ガチな組込みって言うか普通の企業なら開発環境も決め打ちで作ってテストする
2020/03/03(火) 06:53:54.29ID:AJx5UoX4
>>445 > それを言うなら1byte=8bitsとも限らないんで
>>447 > 1 バイトが 8 ビットじゃないアーキテクチャ (で主要 C++ コンパイラがサポートしている環境) が有るんかね?
>>471 > 数年前に触ったdspは1byte32bitだったなー

1byteは8bitと決まってるんですけど…
2020/03/03(火) 07:14:47.35ID:WkxUfZWu
え?
2020/03/03(火) 07:16:59.86ID:KvGr1Z90
なぜuint8_tを使わないの??、、
■ このスレッドは過去ログ倉庫に格納されています
5ちゃんねるの広告が気に入らない場合は、こちらをクリックしてください。

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