1+ use std:: mem:: { size_of, align_of} ;
2+
3+
4+ fn check_size_and_alignment < T > ( size : usize , align : usize ) {
5+ let s = size_of :: < T > ( ) ;
6+ let a = align_of :: < T > ( ) ;
7+
8+ assert_eq ! ( s, size) ;
9+ assert_eq ! ( a, align) ;
10+ }
11+
12+
13+ fn main ( ) {
14+ // // Basic integer types
15+ check_size_and_alignment :: < u8 > ( 1 , 1 ) ;
16+ check_size_and_alignment :: < u32 > ( 4 , 4 ) ;
17+
18+ check_size_and_alignment :: < u8 > ( 1 , 1 ) ;
19+
20+ check_size_and_alignment :: < i8 > ( 1 , 1 ) ;
21+
22+ check_size_and_alignment :: < u16 > ( 2 , 2 ) ;
23+
24+ check_size_and_alignment :: < i16 > ( 2 , 2 ) ;
25+
26+ check_size_and_alignment :: < u32 > ( 4 , 4 ) ;
27+
28+ check_size_and_alignment :: < i32 > ( 4 , 4 ) ;
29+
30+ check_size_and_alignment :: < u64 > ( 8 , 8 ) ;
31+
32+ check_size_and_alignment :: < i64 > ( 8 , 8 ) ;
33+
34+ check_size_and_alignment :: < u128 > ( 16 , 16 ) ;
35+
36+ check_size_and_alignment :: < i128 > ( 16 , 16 ) ;
37+
38+ // // Floating point types
39+ check_size_and_alignment :: < f32 > ( 4 , 4 ) ;
40+
41+ check_size_and_alignment :: < f64 > ( 8 , 8 ) ;
42+
43+ // // Other basic types
44+ check_size_and_alignment :: < bool > ( 1 , 1 ) ;
45+
46+ check_size_and_alignment :: < char > ( 4 , 4 ) ;
47+
48+ // // Pointer-sized types (64-bit)
49+ check_size_and_alignment :: < usize > ( 8 , 8 ) ;
50+
51+ check_size_and_alignment :: < isize > ( 8 , 8 ) ;
52+
53+ check_size_and_alignment :: < & u32 > ( 8 , 8 ) ;
54+
55+ check_size_and_alignment :: < * const u32 > ( 8 , 8 ) ;
56+
57+ check_size_and_alignment :: < * mut u32 > ( 8 , 8 ) ;
58+
59+ // Fat pointers (2x pointer size on 64-bit)
60+ check_size_and_alignment :: < & [ u32 ] > ( 16 , 8 ) ;
61+
62+ // check_size_and_alignment::<&str>(16, 8);
63+
64+ check_size_and_alignment :: < & mut [ u32 ] > ( 16 , 8 ) ;
65+
66+ // // Arrays
67+ check_size_and_alignment :: < [ u8 ; 0 ] > ( 0 , 1 ) ;
68+
69+ check_size_and_alignment :: < [ u8 ; 4 ] > ( 4 , 1 ) ;
70+
71+ check_size_and_alignment :: < [ u8 ; 16 ] > ( 16 , 1 ) ;
72+
73+ check_size_and_alignment :: < [ u32 ; 4 ] > ( 16 , 4 ) ;
74+
75+ check_size_and_alignment :: < [ u64 ; 3 ] > ( 24 , 8 ) ;
76+
77+ // // Tuples
78+ check_size_and_alignment :: < ( ) > ( 0 , 1 ) ;
79+
80+ check_size_and_alignment :: < ( u8 , ) > ( 1 , 1 ) ;
81+
82+ check_size_and_alignment :: < ( u8 , u8 ) > ( 2 , 1 ) ;
83+
84+ check_size_and_alignment :: < ( u8 , u16 ) > ( 4 , 2 ) ;
85+
86+ check_size_and_alignment :: < ( u8 , u32 ) > ( 8 , 4 ) ;
87+
88+ check_size_and_alignment :: < ( u8 , u64 ) > ( 16 , 8 ) ;
89+
90+ check_size_and_alignment :: < ( u32 , u32 ) > ( 8 , 4 ) ;
91+
92+ check_size_and_alignment :: < ( u64 , u8 , u64 ) > ( 24 , 8 ) ;
93+
94+ // rustc will permute fields (less padding)
95+ #[ allow( dead_code) ]
96+ struct Padded {
97+ a : u8 ,
98+ b : u64 ,
99+ c : u8 ,
100+ }
101+ check_size_and_alignment :: < Padded > ( 16 , 8 ) ;
102+
103+ // cannot permute fields
104+ #[ allow( dead_code) ]
105+ #[ repr( C ) ]
106+ struct ReprC {
107+ a : u8 ,
108+ b : u64 ,
109+ c : u8 ,
110+ }
111+ check_size_and_alignment :: < ReprC > ( 24 , 8 ) ;
112+
113+ #[ allow( dead_code) ]
114+ #[ repr( packed) ]
115+ struct ReprPacked {
116+ a : u8 ,
117+ b : u64 ,
118+ c : u8 ,
119+ }
120+ check_size_and_alignment :: < ReprPacked > ( 10 , 1 ) ;
121+
122+ #[ allow( dead_code) ]
123+ struct SmallStruct {
124+ a : u8 ,
125+ b : u8 ,
126+ c : u8 ,
127+ }
128+ check_size_and_alignment :: < SmallStruct > ( 3 , 1 ) ;
129+
130+ #[ allow( dead_code) ]
131+ struct AlignedStruct {
132+ a : u32 ,
133+ b : u32 ,
134+ }
135+ check_size_and_alignment :: < AlignedStruct > ( 8 , 4 ) ;
136+
137+ #[ allow( dead_code) ]
138+ #[ repr( align( 16 ) ) ]
139+ struct Align16 {
140+ a : u8 ,
141+ }
142+ check_size_and_alignment :: < Align16 > ( 16 , 16 ) ;
143+
144+ #[ allow( dead_code) ]
145+ #[ repr( align( 32 ) ) ]
146+ struct Align32 {
147+ a : u32 ,
148+ }
149+ check_size_and_alignment :: < Align32 > ( 32 , 32 ) ;
150+
151+ // Enums
152+ #[ allow( dead_code) ]
153+ enum SimpleEnum {
154+ A ,
155+ B ,
156+ C ,
157+ }
158+ check_size_and_alignment :: < SimpleEnum > ( 1 , 1 ) ;
159+
160+ #[ allow( dead_code) ]
161+ enum EnumWithData {
162+ Variant1 ( u32 ) ,
163+ Variant2 ( u64 ) ,
164+ }
165+ check_size_and_alignment :: < EnumWithData > ( 16 , 8 ) ;
166+
167+ #[ allow( dead_code) ]
168+ enum ComplexEnum {
169+ Small ( u8 ) ,
170+ Medium ( u32 ) ,
171+ Large ( u64 , u64 ) ,
172+ }
173+ check_size_and_alignment :: < ComplexEnum > ( 24 , 8 ) ;
174+
175+ // // Option optimization
176+ check_size_and_alignment :: < Option < u32 > > ( 8 , 4 ) ;
177+
178+ check_size_and_alignment :: < Option < u64 > > ( 16 , 8 ) ;
179+
180+ // Null pointer optimization
181+ check_size_and_alignment :: < Option < & u32 > > ( 8 , 8 ) ;
182+
183+ check_size_and_alignment :: < Option < Box < u32 > > > ( 8 , 8 ) ;
184+
185+ // Result
186+ check_size_and_alignment :: < Result < u32 , u32 > > ( 8 , 4 ) ;
187+
188+ check_size_and_alignment :: < Result < u64 , u8 > > ( 16 , 8 ) ;
189+
190+ // Zero-sized types
191+ struct ZeroSized ;
192+ check_size_and_alignment :: < ZeroSized > ( 0 , 1 ) ;
193+
194+ struct PhantomStruct < T > {
195+ _marker : std:: marker:: PhantomData < T > ,
196+ }
197+ check_size_and_alignment :: < PhantomStruct < u64 > > ( 0 , 1 ) ;
198+
199+ // // String and Vec (heap-allocated)
200+ check_size_and_alignment :: < String > ( 24 , 8 ) ;
201+
202+ check_size_and_alignment :: < Vec < u32 > > ( 24 , 8 ) ;
203+
204+ check_size_and_alignment :: < Box < u32 > > ( 8 , 8 ) ;
205+
206+ check_size_and_alignment :: < Box < [ u32 ] > > ( 16 , 8 ) ;
207+
208+ }
0 commit comments