Dlaczego sizeof nazywany jest operatorem czasu kompilacji?

12

Pierwotnie jest to część innego pytania.

Dlaczego sizeofnazywany jest operatorem czasu kompilacji? Czy to właściwie nie jest operator czasu wykonywania? A jeśli rzeczywiście jest to operator czasu kompilacji, w jaki sposób pomaga w tworzeniu przenośnego kodu, który działa tak samo na różnych komputerach? Proszę wyjaśnić szczegółowo.

Peaceful Coder
źródło
4
szczegółowo odpowiedział na SO: Dlaczego sizeof (x ++) nie inkrementuje x?
komar
3
Jak spodziewacie się zmiany rozmiaru typu w czasie wykonywania?
@MichaelT: Rozmiar instancji typu może z pewnością się zmienić - w końcu istnieje polimorfizm klas. Twierdzę, że sizeof(polymorphic_ptr*)bycie stałym jest sprzeczne z intuicją i po prostu głupie. Tak, to sposób w C ++, ale głupiutki.
Przywróć Monikę
@KubaOber Rzeczywiście. Jestem tylko ciekawy, jak OP pomyślał, że powinien on zachowywać się w różnych przypadkach, i mam nadzieję, że dostanę kod, który zademonstruje jego zamieszanie, aby pomóc w rozszerzeniu pytania.
4
Przyszedł głosować za odpowiedzią „ponieważ działa w czasie kompilacji”, rozczarowany.
Ben Jackson

Odpowiedzi:

23

sizeof()daje rozmiar typu danych , a nie rozmiar konkretnej instancji tego typu w pamięci.

Na przykład, jeśli miałeś obiekt danych ciągu, który przydzielił tablicę znaków o zmiennej wielkości w czasie wykonywania, sizeof()nie można użyć do określenia rozmiaru tej tablicy znaków. Dałoby to tylko rozmiar wskaźnika.

Rozmiar typu danych jest zawsze znany w czasie kompilacji.


źródło
3
Ponieważ C (++) nie ma metadanych obiektów w czasie wykonywania, nie można tak naprawdę uzyskać tych rzeczy w czasie wykonywania.
C. Ross
5
Właściwie, jeśli używasz sizeofna tablicy, to będzie uzyskać rozmiaru tablicy (czyli razy rozmiar elementu liczba elementów). Ale jeśli użyjesz go na wskaźniku, otrzymasz tylko rozmiar wskaźnika. Tak więc, ponieważ w większości przypadków, gdy chcesz poznać rozmiar tablicy, masz tylko wskaźnik, nie jest to aż tak przydatne.
sepp2k 18.04.13
1
@Jens Pytanie jest oznaczone [C ++], a VLA nie weszło do standardu C ++.
authchir 18.04.13
13

ponieważ cały rozmiar „wywołania” jest obliczany w czasie kompilacji, a cokolwiek między nawiasami jest odrzucane i nie jest uruchamiane w czasie wykonywania,

wynik opiera się wyłącznie na informacjach o typie statycznym dostępnych dla kompilatora

maniak zapadkowy
źródło
7

Dlaczego sizeof nazywany jest operatorem czasu kompilacji?

Ponieważ w czasie kompilacji kompilator oblicza wielkość wyrażenia i zastępuje stałą wartość czasu kompilacji.

Czy to właściwie nie jest operator czasu wykonywania?

Nie. Możesz nawet użyć sizeofdo oceny rozmiaru wyrażeń, których nie możesz legalnie wykonać (tj. Spowodowałoby to Niezdefiniowane Zachowanie), o ile kompilator może dowiedzieć się, jaki jest typ wyrażenia.

Ponadto, nawet przed C ++ 11 constexpr, możesz używać sizeofwyrażeń w sposób, w jaki nie możesz używać wyrażeń wykonawczych.

A jeśli rzeczywiście jest to operator czasu kompilacji, w jaki sposób pomaga w tworzeniu przenośnego kodu ...

Typy mogą różnić się rozmiarem na różnych platformach. Używanie sizeofwyrażeń zamiast zakodowanych na stałe założeń oznacza, że ​​Twój kod nie ulegnie awarii, gdy kompilujesz na innej platformie, a typy zmieniają rozmiar.

Nieprzydatny
źródło
1
Cóż, uważam to za najbardziej przydatną odpowiedź;). Bro (zakładając, że jesteś mężczyzną), mam wątpliwości. Czy chcesz powiedzieć, że kiedy ludzie mówią, że sizeof sprawia, że ​​programy są przenośne, oznaczają, że kod źródłowy można skompilować bez błędów na wszystkich komputerach i nie oznacza to, że program wykonywalny można uruchomić na dowolnej maszynie. Dobrze ? Jeśli to prawda, moje wątpliwości zostają naprawdę wyjaśnione.
The Peaceful Coder,
1
Tak, kod jest przenośny, w tym sensie, że możesz skompilować (inny) poprawny plik binarny dla każdej platformy.
Bezużyteczne
5

C ++ tak naprawdę nie przechowuje metadanych dla obiektów w czasie wykonywania, więc sprawdzanie rozmiaru musi być czasem kompilacji. Na przykład, jak C ++ nie sprawdza poprawności rozmiaru, zadeklaruj tablicę o intdowolnym rozmiarze i odczytaj poza jej końcem. Jeśli masz szczęście, dostaniesz, segfaultale bardziej prawdopodobne, że po prostu przeczytasz bełkot, ponieważ C ++ nie śledzi rozmiaru twojej tablicy.

Zobacz: Czy program C / C ++ może uszkodzić program przed odczytem poza końcem tablicy (UNIX)? na przykład z SO.

Krzyż
źródło