2014-11-05 23 views

Odpowiedz

13

printf jest funkcją variadic i musi być przekazywana argumenty odpowiednich typów. Standard mówi, że %p pobiera void *.

Implicit cast doesn't take place dla variadic functions.

Cytując N15707.21.6.1 Funkcja fprintf

P: argumentem powinien być wskaźnikiem do unieważnienia. Wartość wskaźnika to przekształcona na sekwencję znaków drukarskich, w sposób określony przez implementację .

+0

Zauważ, że twój cytat to na pewno POSIX-specyficzny, IIRC standardowy mandat tylko, że dwa różne wskaźniki mają różne wyniki specyficzne dla realizacji. –

+0

@MatteoItalia Dzięki. Zaktualizowano. –

+0

Ładne cytowanie, ale w praktyce, w jaki sposób fakt, że ** niejawne rzutowanie nie ma miejsca ** wpływa na wartość przekazywanego argumentu (innymi słowy, w jaki sposób rzutowanie na 'void *' może uczynić wartość ' pi' any different)? –

8

Prezentacja wewnętrzna lub rozmiar różnych typów wskaźników niekoniecznie musi być taki sam.

Na przykład na jednym systemie sizeof(void*) może być 2, ale sizeof(int*) to 1.

Od printf jest funkcja zmiennej argumentem, że nie można sprawdzić typy parametrów przychodzących. Jeśli przekażemy mu numer int*, odczyta on niepoprawną liczbę bajtów, ponieważ oczekuje ona od void*.

8

Specyfikacja konwersji w printf wymaga argumentu typu void *. C mówi, że jeśli przekazujesz argument innego typu, wywołanie wywołuje niezdefiniowane zachowanie.

Poza tym, obiekty wskaźnika różnych typów nie muszą mieć tej samej reprezentacji: C nie gwarantuje na przykład, że sizeof (void *) == sizeof (int *). C gwarantuje tylko, że void * ma taką samą reprezentację jak wskaźniki dla typów znaków.

+0

Nie powiedziałbym "Poza tym", ale raczej "To dlatego": jeśli nr 2 nie miało to miejsca, nie było powodu dla # 1. Znaczy to, że gdyby wszystkie wskaźniki wyglądały jak inne pod względem układu pamięci, nie byłoby potrzeby określania UB dla nie-unikalnych '' * '. – glglgl

+0

@glglgl Nadal wolę "poza tym", ponieważ oprócz C mówiąc, że * Wskaźniki do innych typów nie muszą mieć tego samego wymagania reprezentacji lub wyrównania * istnieje specjalna reguła C dla funkcji 'fprintf', która mówi o argumencie dla' p "będzie wskaźnikiem' void * '. – ouah

+0

Masz rację, ale wzajemna więź między nimi pozostaje. – glglgl