エラー、バグ、質問 - ページ 2503

削除済み  
Alexey Viktorov:

では、どんなバグがあるのでしょうか?

2つの要素を2バイトずつ持つ配列を宣言し、本来であれば4バイトを取得します。バグはどこですか?何ですか?

これなんです。

4にアラインして、2つの要素が2*8バイトを占有することになります。

申し訳ないが、そう書くと理解できないだろう。

十字架と類似している。

#include <iostream>
struct alignas(4) A
{
  short j;
};

int main()
{
   A q[2];
   std::cout << sizeof(q) << std::endl; // 8
   return 0;
}

間違いはおそらくここではないのでは?

 
Vict:

申し訳ないが、そう書くと、このテーマを理解していないことになる。

いや、わかっていないようですね。

//g++  5.4.0

#include <iostream>
#pragma  pack (push, 4)
struct A
{
  short j;
};
#pragma  pack (pop)

int main()
{
   A q[2];
   std::cout << sizeof(q) << std::endl; // 4
   return 0;
}
削除済み  
TheXpert:

いや、わかっていないようですね。

smallmicrosoftのものの#pragmaパックは非常に特殊なものです(その動作原理には今更ながら驚きました、率直なところ)。当然のことながら、標準的なアライナの動作は異なる。

こちらもどうぞ。

#include <iostream>
struct A
{
  short j;
} __attribute__((aligned(4)));

int main()
{
   A q[2];
   std::cout << sizeof(q) << std::endl; // 8
   return 0;
}
 
Vict:

小型ソフトの#pragmaパックは非常にクセモノです(今となってはその仕組みに驚かされます、正直なところ)。アライナスの動作が規格で違うのも頷けます。

おいおい)

#include <iostream>
struct A
{
  short j;
} alignas(4) ;

int main()
{
   A q[2];
   std::cout << sizeof(q) << std::endl; // 4
   return 0;
}

gccでも#pragma packは正常に動作しますし、あなたが書いたものは、単にgccの内部属性で、alignedとは異なる動作をするものです。

削除済み  
TheXpert:

さあ、もう)

gccでも#pragma packは正常に動作しますし、あなたが書いたものはgccの内部属性に過ぎず、alignedと同じようには動作しません。

では、この例は何を示しているのでしょうか。アライナの使い方がわかっていないこと?コンパイラーも悪態をつくコード。

1.cc:7:3: warning: attribute ignored in declaration of 'struct A' [-Wattributes]
    7 | } alignas(4) ;
      |   ^~~~~~~
1.cc:7:3: note: attribute for 'struct A' must follow the 'struct' keyword

プラグマパックは、gccが互換性のためにのみサポートする、奇妙で小さなソフティーの創造物です。

 
Vict:

では、この例は何を示しているのでしょうか。アライナの使い方がわからないと?

そうですね、失敗しちゃいました。

これが正しいコードです。

#include <iostream>
struct alignas(4) A
{
  short j;
}  ;

int main()
{
   A q[2];
   std::cout << sizeof(q) << std::endl; // 8
   return 0;
}

ということで、alignasはパッケージングに類するものではありません。

というのも、同じgcc(smallsoftなしの場合)では、デフォルトのパッキング倍率は8だからです。

なぜなら

#include <iostream>
struct A
{
  short j;
};

struct B
{
  short j;
  long long k;
};

int main()
{
   A q[2];
   B r[2];
   std::cout << sizeof(q) << " " << sizeof(r) << std::endl; // 4 32
   return 0;
}

が、alignas(8) を使って

#include <iostream>
struct alignas(8) A
{
  short j;
};

struct alignas(8) B
{
  short j;
  long long k;
};

int main()
{
   A q[2];
   B r[2];
   std::cout << sizeof(q) << " " << sizeof(r) << std::endl; // 16 32
   return 0;
}
 
また、これはデフォルトの動作であり、ソフトウェアとの互換性のためではないことに注意してください。
削除済み  
TheXpert:
また、これはデフォルトの動作であり、Smallmicrosoftとの互換性を保つためのものではないことに注意してください。

その発想はない。例ではすべてうまくいっています、問題はありません。デフォルト - 構造体のアライメント == メンバー間の最も厳しい要求アライメントを取る。

struct {char;}== 1、struct {char;short} == 2、struct {char;int} == 4、など。どこもそうなんですね。また、long long == eight なので、alignas は何の効果もない。

 
Vict:

その発想はない。例ではすべてうまくいっているので、問題はないと思います。

たしかに、この例は指標になりませんね。

要するに、mql pack は #pragma pack として動作し、alignas ではないということです。

 
人、情報を共有する。アライメントを何に使うのか?