私はもともとタブレットからこの質問を書き、多くのショートカットを使用したため、最終的に質問を読んだり、質問に答えようとしたりする人々に混乱を招くと思います.
私が最初に抱えていた問題の解決策を求めているわけではありません。裏話が本当に必要な場合は次の段落を読み、それ以外の場合はスキップしてください。
{struct, data, struct, data, ...}
これを引き起こしたのは、それぞれdata
が任意の長さを持つ形式のデータの配列を操作する古いコードです。コードはポインターを介して各構造体にアクセスし、gcc に切り替えたときに、Solaris でミスアライン アクセスが原因でクラッシュし始めました。これを解決するための 1 つのアイデアは、以下に示すように型のアラインメントを変更することでしたが、私はおそらくそうするつもりはありません。
回答すべき質問は次のように要約できます。
- ドキュメントには、アラインメントを で減らすことはできないと記載さ
aligned
れていますが、typedef で行うことができます。意図したとおりに機能していますか? - 意図したとおりに機能している場合、なぜ typedef が必要なのですか? 構造体定義の一部としてアラインメントを下げることができないのはなぜですか?
- 注:それ
typedef struct {...}__attribute__((aligned(1))) Typename;
も同様に行うことができます
- 注:それ
wandbox で実行されているサンプル コードへのリンクを次に示します。リンクが切れた場合:
#include <cstdio>
#include <assert.h>
#define ALIGN __attribute__((aligned(1)))
struct Misaligned_1_t { int x; double y; float z; };
struct ALIGN Misaligned_2_t { int x; double y; float z; };
struct Misaligned_3_t { int x; double y; float z; } ALIGN;
// The gcc documentation indicates that the "aligned" attribute
// can only be used to increase alignment, so I was surprised
// to discover this actually works. Why does it work?
typedef Misaligned_1_t ALIGN Aligned_t;
int main( int, char** ) {
char buffer[256];
// The following is meant to simulate a more complicated scenario:
// {SomeStruct, char[arbitrary length], SomeStruct, char[arbitrary length], ...}
// ... where accessing, using and changing each SomeStruct will result in
// misaligned accesses.
auto *m1 = (Misaligned_1_t*)&buffer[1];
auto *m2 = (Misaligned_1_t*)&buffer[1];
auto *m3 = (Misaligned_1_t*)&buffer[1];
auto *a1 = (Aligned_t*)&buffer[1];
// The documentation says we can only reduce alignment with the "packed" attribute,
// but that would change the size/layout of the structs. This is to demonstrate
// that each type is the same size (and should have the same layout).
assert( sizeof(m1) == sizeof(m2)
&& sizeof(m1) == sizeof(m3)
&& sizeof(m1) == sizeof(a1) );
m1->y = 3.14159265358979323846264; // misaligned access
std::printf( "%0.16f\n", m2->y ); // misaligned access
std::printf( "%0.16f\n", m3->y ); // misaligned access
std::printf( "%0.16f\n", a1->y ); // works fine
return 0;
}