Możemy przyjrzeć się reprezentacji obiektu typu T
, konwertując obiekt T*
, który wskazuje na ten obiekt na char*
. Przynajmniej w praktyce:Kiedy i jak jest dozwolona konwersja do wskaźnika znaków?
int x = 511;
unsigned char* cp = (unsigned char*)&x;
std::cout << std::hex << std::setfill('0');
for (int i = 0; i < sizeof(int); i++) {
std::cout << std::setw(2) << (int)cp[i] << ' ';
}
ten wyprowadza reprezentację 511
na moim systemie: ff 01 00 00
.
Występuje tu (na pewno) pewne zachowanie związane z implementacją. Która z odlewów pozwala mi przekonwertować int*
na unsigned char*
i jakie konwersje powodują, że ta obsada ma miejsce? Czy przywołuję niezdefiniowane zachowanie, gdy tylko rzucę? Czy mogę obsłużyć dowolny typ T*
? Na czym mogę polegać, kiedy to robię?
Nie sądzę, że to niezdefiniowane zachowanie, przynajmniej jeśli nie modyfikujesz danych.Ale wynik będzie zależał od tego, czy platforma jest mała, czy wielka endian. – Synxis
Należy pamiętać, że jest to bezpieczne tylko dla 'char *'. Wskaźniki rzutowania, aby były odczytywane jako różne typy, powodują problemy z * aliasingiem *. Języki C i C++ gwarantujące kompilatorowi, który wskazuje na różne typy, nigdy nie mogą wskazywać na ten sam obiekt, więc optymalizator może np. Przechowywać wartość w rejestrze lub podnieść ładunek lub napisać z pętli. "char *" jest jedynym wyjątkiem. Należy przypisać 'char *' do aliasu ze wszystkim, z powodu serializacji do iz buforów dyskowych i sieciowych. –
@ZanLynx - Re "' char * 'jest jedynym wyjątkiem": Niezupełnie. Standard umożliwia również konwersję na "unsigned char *". –