Kitapta nesne üyelerinin yerleşimlerini aralarındaki doldurma baytlarıyla birlikte gösteren bir kod var:
http://ddili.org/ders/d/bellek_yonetimi.html#ix_bellek_yonetimi..offsetof
Oradaki işlevi üyelerin kapsadıkları baytları Unicode karakterleriyle gösterecek biçimde biraz geliştirdim:
void nesneYerleşiminiYazdır(T)()
if (is (T == struct) || is (T == union)) {
import std.stdio;
import std.string;
writefln("=== '%s' nesnelerinin yerleşimi (.sizeof: %s, .alignof: %s) ===",
T.stringof, T.sizeof, T.alignof);
/* Üyeyle (veya doldurma baytlarıyla) ilgili bilgi yazdırır.
*
* başlangıç: Üyenin nesne içindeki yeri (offset)
* miktar: Üyenin kaç baytlık olduğu (sizeof)
* bilgi: Yazdırılacak olan bilgi
*/
void üyeYazdır(size_t başlangıç, size_t miktar, string bilgi) {
assert(miktar != 0);
/* Üyenin bayt kapsamını görselleştirmek için bu satırda
kullanılması gereken karakteri döndürür. */
auto çizgiKarakteri(size_t satır) {
if (miktar == 1) {
assert(satır == 0);
return '╶';
} else {
if (satır == 0) {
return '┌';
} else if (satır == miktar - 1) {
return '└';
}
else {
return '│';
}
}
}
// Bilginin ortalanmış olarak görünmesi için kullanılan satır numarası
const bilgiSatırıNumarası = (miktar - 1) / 2;
foreach (satır; 0 .. miktar) {
writef("%4s %s", başlangıç + satır, çizgiKarakteri(satır));
if (satır == bilgiSatırıNumarası) {
writef(" %s, %s bayt", bilgi, miktar);
}
writeln();
}
}
/* Doldurma varsa miktarını yazdırır. */
void doldurmaBilgisiYazdır(size_t beklenenUzaklık, size_t gözlemlenenUzaklık) {
if (beklenenUzaklık < gözlemlenenUzaklık) {
/* Gözlemlenen uzaklık beklenenden fazlaysa doldurma baytı var
* demektir. */
const doldurmaMiktarı = gözlemlenenUzaklık - beklenenUzaklık;
üyeYazdır(beklenenUzaklık, doldurmaMiktarı, "DOLDURMA");
}
}
/* Bir sonraki üyenin doldurma olmayan durumda nerede olacağı bilgisini
* tutar. */
size_t doldurmasızUzaklık = 0;
/* Not: __traits(allMembers) bir türün üyelerinin isimlerinden oluşan bir
* 'string' topluluğudur. */
foreach (üyeİsmi; __traits(allMembers, T)) {
mixin (format("alias üye = %s.%s;", T.stringof, üyeİsmi));
// Bir sonraki üyeyi yazdırmadan önce varsa doldurma bilgisini yazdır
const uzaklık = üye.offsetof;
doldurmaBilgisiYazdır(doldurmasızUzaklık, uzaklık);
// Şimdi bu üyeyi yazdır
const türİsmi = typeof(üye).stringof;
const miktar = üye.sizeof;
üyeYazdır(uzaklık, miktar, format("%s %s", türİsmi, üyeİsmi));
doldurmasızUzaklık = uzaklık + miktar;
}
// Varsa son üyeden sonraki doldurma bilgisini yazdır
doldurmaBilgisiYazdır(doldurmasızUzaklık, T.sizeof);
}
struct A {
byte b;
int i;
ubyte u;
string s;
byte b2;
double d;
}
void main() {
nesneYerleşiminiYazdır!A();
}
'
=== 'A' nesnelerinin yerleşimi (.sizeof: 48, .alignof: 8) ===
0 ╶ byte b, 1 bayt
1 ┌
2 │ DOLDURMA, 3 bayt
3 └
4 ┌
5 │ int i, 4 bayt
6 │
7 └
8 ╶ ubyte u, 1 bayt
9 ┌
10 │
11 │
12 │ DOLDURMA, 7 bayt
13 │
14 │
15 └
16 ┌
17 │
18 │
19 │
20 │
21 │
22 │
23 │ string s, 16 bayt
24 │
25 │
26 │
27 │
28 │
29 │
30 │
31 └
32 ╶ byte b2, 1 bayt
33 ┌
34 │
35 │
36 │ DOLDURMA, 7 bayt
37 │
38 │
39 └
40 ┌
41 │
42 │
43 │ double d, 8 bayt
44 │
45 │
46 │
47 └
'
Ali
--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]