Wykorzystanie pamięci jest dość krytyczne w mojej aplikacji. Dlatego mam konkretne potwierdzenia, które sprawdzają rozmiar pamięci w czasie kompilacji i dają static_assert, jeśli rozmiar jest inny niż wcześniej uważaliśmy za poprawny.Jak połączyć static_assert z sizeof i stringify?
Mam zdefiniowane makra tak:
#define CHECKMEM(mytype, size) static_assert((sizeof(objectType) == size)), "Size incorrect for " #mytype "!");
To makro sprawia, że bardzo łatwo pisać to:
CHECKMEM(Book,144);
CHECKMEM(Library,80);
Problem polega na tym, że gdy ten static_assert gaśnie, może to być dość trudno dowiedzieć się, jaki powinien być nowy rozmiar (np. używając ukrytej opcji kompilatora "/ d1 reportAllClassLayout"). Byłoby znacznie wygodniej, gdybym mógł uwzględnić rzeczywisty rozmiar, więc zamiast:
Niepoprawny rozmiar dla książki!
Byłoby pokazać
Rozmiar nieprawidłowy dla książki! (Oczekiwano 144, rozmiar to 152)
Próbowałem pisać coś takiego:
#define CHECKMEM(mytype, size) static_assert((sizeof(objectType) == size)), "Size incorrect for " #mytype "! (expected" #size ", size is " #sizeof(mytype) ")");
Ale nie można używać operatora (#) stringize na wywołaniu funkcji.
Próbowałem też dodanie trick dwukrotnie stringize, tak:
#define STR1(x) #x
#define STR2(x) STR1(x)
#define CHECKMEM(mytype, size) static_assert((sizeof(objectType) == size)), "Size incorrect for " #mytype "! (expected" #size ", size is " STR2(sizeof(mytype)) ")");
Ale zamiast drukować size is 152
drukuje size is sizeof(Book)
.
Czy istnieje sposób na łańcuchowanie wyniku sizeof w static_assert?
Zauważ, że 'sizeof' to * nie * wywołanie funkcji –
Problem polega na tym, że drugi argument polecenia' static_assert' musi być literałem łańcuchowym i nie możesz go zbudować w preprocesorze, ponieważ nie możesz użyć sizeof tam . – pmr