18

alignas の使用方法を理解しようとしています。プラグマ パックの代わりになるのではないかと思います。検証しようと努力しましたが、うまくいきませんでした。gcc 4.8.1 ( http://ideone.com/04mxpI ) を使用すると、STestAlignas の下で常に 8 バイトを取得しますが、プラグマ パックでは 5 バイトです。私が達成したいのは、sizeof(STestAlignas) が 5 を返すようにすることです。clang 3.3 ( http://gcc.godbolt.org/ ) でこのコードを実行しようとしましたが、エラーが発生しました:

!!エラー: 要求されたアラインメントは、タイプ 'long' の最小アラインメント 8 未満です - alignas の使用法のすぐ下です。

では、alignas の最小アライメント値はあるのでしょうか?

以下は私のテストコードです:

#include <iostream>
#include <cstddef>
using namespace std;

#pragma pack(1)
struct STestPragmaPack {
  char c;
  long d;
} datasPP;
#pragma pack()

struct STestAttributPacked {
  char c;
  long d;
} __attribute__((packed)) datasAP;

struct STestAlignas {
  char c;
  alignas(char) long d;
} datasA;

int main() {
    cout << "pragma pack = " << sizeof(datasPP) << endl;
    cout << "attribute packed = " << sizeof(datasAP) << endl;
    cout << "alignas = " << sizeof(datasA) << endl;
}

gcc 4.8.1 の結果:

pragma pack = 5
attribute packed = 5
alignas = 8

[26.08.2019]

このトピックには標準化の動きがあるようです。p1112 提案 -クラス レイアウト制御の言語サポート- (とりわけ)[[layout(smallest)]]アラインメント コストをできるだけ小さくするためにクラス メンバーを並べ替える属性を追加することを提案します (これはプログラマーの間で一般的な手法ですが、クラス定義の読みやすさを損なうことがよくあります)。 . しかし、これはpragma(pack) が行うことと同じではありません!

4

3 に答える 3

17

alignas交換できません#pragma pack

GCC はalignas宣言を受け入れますが、メンバーを適切に配置したままにします。最も厳密な配置要件 (この場合は の配置long) を満たすことで、指定した要件も満たされます。

ただし、GCC は、標準が §7.6.2 のパラグラフ 5 でこれを実際に明示的に禁止しているため、寛大すぎます。

宣言内のすべての配置指定子の結合された効果は、すべての配置指定子が省略された場合に宣言されるエンティティに必要な配置よりも厳密でない配置を指定してはなりません (他の宣言の配置を含む)。

于 2013-09-24T09:43:47.463 に答える
2

調整されていないデータや調整されていないデータを扱うことにはリスクがあり、コストがかかることをご存知だと思います。

たとえば、整列されていない 5 バイトのデータ構造を取得すると、8 バイトの整列されたデータ構造を取得するよりも時間がかかります。これは、5 "... バイト データがこれらの 4 バイト境界のいずれかで始まらない場合、コンピューターはメモリを 2 回読み取り、内部で 4 バイトを 1 つのレジスタにアセンブルする必要がある" (1) ためです。

調整されていないデータを扱うには、より多くの数学的演算が必要であり、ECU による時間 (および電力) の消費が増加します。

C と C++ はどちらも「ハードウェアに優しい」言語であると考えられていることを考慮してください。これは、「最小メモリ使用量」の言語だけでなく、主に効率と高速処理に重点を置いた言語を意味します。データの整列 (「保存する必要がある」ために厳密に必要でない場合) は、別の概念を暗示する概念です。「多くの場合、ソフトウェアとハ​​ードウェアは人生に似ています。より良い結果を得るには犠牲が必要です!」.

また、間違った仮定を持っていないか自問することも検討してください。のようなもの:「小さい/st 構造 => 高速/st 処理」。もしそうなら、あなたは(完全に)間違っているかもしれません。

しかし、あなたのポイントが次のようなものであると仮定すると: あなたはソフトウェアの効率、電力消費、および高速性についてはまったく気にしませんが、(ハードウェアの制限のため、または単に理論的な関心のために) 「最小限のメモリ使用量」、そしておそらく次の読み方が役に立つかもしれません:

(1) C++ でアラインされていないメモリを宣言、操作、およびアクセスする

(2) C アラインメントの問題の回避

ただし、次の内容を必ずお読みください。

(3)アラインされていないメモリアクセスについて標準は何と言っていますか?

この標準の抜粋にリダイレクトするもの:

(4) http://eel.is/c++draft/basic.life#1

(5)非境界メモリ アクセス: 動作が定義されているかどうか。[これは重複していますが、追加情報が含まれている可能性があります]。

于 2019-08-24T20:35:48.563 に答える