2013-05-14 9 views
5

§6.5.8\6 (dotyczące>, <, < => =)Strange sformułowanie standardu dotyczącego porównania wskaźników

Jeśli punkty ekspresja P do elementu obiektu tablicy i punktami Q ekspresyjnych do ostatniego elementu tego samego obiektu tablicy, wyrażenie wskaźnika Q + 1 porównuje wartość większą niż P. We wszystkich innych przypadkach zachowanie jest niezdefiniowane.

Kilka sekcji powyżej, §6.5.8, wyjaśnia, że ​​w zasadzie praca arytmetyczna wskaźnikowa zgodnie z oczekiwaniami na tablicach. To jest int a[3]; int *p = a; int *q = &a[2]; //q-p == 3 jest prawidłowe. Jednak, jak czytam powyższy q > p jest UB.

Czego mi brakuje?

+6

Brakuje zdania poprzedzającego poprzednie: "wskaźniki do elementów tablicy z większymi wartościami indeksu dolnego porównują większe niż wskaźniki do elementów tej samej tablicy z dolnym indeksem dolnym".To, co cytujesz, to wyjątek, który pozwala na półotwartych zakresów takich jak ['a',' a + 3'). – dyp

+0

@DyP, Oh, dobrze. Musiałem przeczytać to jeszcze 5 razy, żeby to zrozumieć. Kolejne głupie pytanie z mojej strony :( – Vorac

+1

To Standard, niektórzy twierdzą, że to Standard dla trudnych i nieintuicyjnych formuł;) – dyp

Odpowiedz

1

Po pierwsze, już cytowany częścią ustępu, pierwsza część wyjaśnia, co to jest odniesienie, ja to paragraf tutaj:

Gdy dwa wskaźniki są porównywane, wynik zależy od względnej lokalizacjach przestrzeń adresowa wskazanych obiektów. Jeśli dwa wskaźniki dla typów obiektów wskazują zarówno na ten sam obiekt, jak i na punkt jeden za ostatnim elementem tego samego obiektu tablicy, to są one równe. Jeśli wskazane obiekty są członkami tego samego obiektu zbiorczego, to zadeklarowane później wskaźniki elementów struktury są porównywane wyżej niż wskaźniki do elementów zadeklarowanych wcześniej w strukturze, a wskaźniki do elementów tablicy z większymi wartościami indeksu niższego niż wskaźniki do elementów ta sama tablica z niższymi wartościami dolnego indeksu. Wszystkie wskaźniki do członków tego samego obiektu związku są takie same. Jeśli wyrażenie P wskazuje na element obiektu tablicy, a wyrażenie Q wskazuje na ostatni element tego samego obiektu tablicy, wyrażenie wskaźnika Q + 1 porównuje wartość większą niż P. We wszystkich innych przypadkach zachowanie jest niezdefiniowane.

Zasadniczo nieco ty przedstawieniu odnosi się do faktu, że zazwyczaj wskaźnik zawsze musi punkt albo samodzielne obiektu do elementu tablicy obiektów lub jednym poza koniec tablicy obiektów. Jak widać, zwykle zwiększanie wskaźnika, który już wskazuje na ostatni element tablicy, spowodowałoby niepoprawny wskaźnik, a tak naprawdę ten wskaźnik w standardzie nie może być nigdy dereferencjonowany, jednak można go użyć w jednym szczególnym przypadku, tj. można ustawić lub porównać z innym wskaźnikiem.

Jest to przydatne w programie, w którym zwiększasz wskaźnik, a następnie sprawdzasz, czy jest on poza końcem tablicy i kończy się, jeśli tak się stanie. Na przykład.

Będzie legalny, nawet w ostatnim przypadku, gdy foo wskazuje jeden poza koniec tablicy.

Uwaga: ten przykład jest bardzo wymyślny, ale demonstruje punkt.

Jeśli nie dla tej reguły, ten program będzie niezdefiniowanym zachowaniem.

+0

Ostatnia iteracja powoduje niezdefiniowane zachowanie w kodzie przykładowym. 'bar + 7' powoduje, że UB pod sekcją o tym, co' + 'oznacza dla wskaźnika plus liczba całkowita. –

+0

@MattMcNabb Argh, masz rację, użyłem niewłaściwego operatora, zamierzałem użyć <. Dosłownie wymieszałem te dwie setki razy, pomyślałbym po prawie 15 latach C, uniknęłbym tego głupiego błędu. Mimo to, dziękuję za komentarz, myślę, że teraz jest naprawiony. – Vality

+1

@MattMcNabb Zdaję sobie sprawę, że nie ma wyjątku dla Q + 2, błędu, który popełniłem i zawsze robię to, że długość tablicy! = Indeks ostatniego elementu. Zawsze liczę od 1, a nie od zera :( – Vality