Krump |
» 2015-01-04 01:27:18 Jeszcze niektóre rzeczy na nim się pisze ;) Ale niestety w większości to producenci narzucają, a od zera tworzenie układu cyfrowego jest nieoplacalne. |
|
DejaVu |
» 2015-01-04 01:42:43 http://timepp.drivehq.com/cpp11/data/expr.add.htmlhttp://c0x.coding-guidelines.com/6.5.6.htmlhttp://programmers.stackexchange.com/questions/247233/pointer-indexing1170 If both the pointer operand and the result point to elements of the same array object, or one past the last element of the array object, the evaluation shall not produce an overflow;
1171 otherwise, the behavior is undefined.
|
Dodatkowo: The additive operators + and - group left-to-right.
|
Czyli kompilator wg standardu powinien wykonać takie obliczenia: char tekst[] = "abc"; char * ptr = tekst; ptr = ptr - 1; ptr = ptr + strlen( tekst );
Czyli zachowanie jest de-facto niezdefiniowane, bo wskaźnik wychodzi poza zakres tablicy. /edit: Podsumowując, powyższe paragrafy implikują to co zostało napisane pod adresem http://c-faq.com/aryptr/non0based.html, czyli: Pointer arithmetic is defined only as long as the pointer points within the same allocated block of memory, or to the imaginary ``terminating'' element one past it; otherwise, the behavior is undefined, even if the pointer is not dereferenced.
|
Wspomniane zapisy występują zarówno w standardzie języka C jak i w standardzie języka C++. /edit2: W ogóle nie wiem, skąd ta dyskusja, w tym wątku. temat został dawno rozwiązany, a ostatnie strony to tylko jakaś przepychanka. Prosiłbym o pomoc w innych tematach, a nie kłócenie się o rzecz rozwiązaną w tym.
|
@Krump: wymieniamy się wiedzą, której nie znajdziesz w podręcznikach ani książkach. Ta dyskusja ma sens. |
|
SocrateZ |
» 2015-01-04 02:00:53 Z powyższego linku (c-faq.com) warto wyciąć również i to zdanie: The code above computes a pointer to memory before the beginning of realarray and could fail if, while subtracting the offset, an illegal address were generated (perhaps because the address tried to "wrap around" past the beginning of some memory segment). |
Czy adres nie zostanie przypadkiem ustalony po wykonaniu całego działania? |
|
DejaVu |
» 2015-01-04 02:45:12 Operacje dodawania i odejmowania wykonywane są od lewej do prawej (tak jak zacytowałem). To, że nie widać wyników pośrednich nie oznacza, że nie są one 'gdzieś' przechowywane. Wynik pośredni wychodzi poza zakres więc zgodnie ze standardem zachowanie jest niezdefiniowane. Po to są nawiasy () aby wymusić inną kolejność wykonywania działań. W tym wypadku wspomniane nawiasy nie występują, więc kompilator przetworzy te dane w takiej samej kolejności w jakiej użytkownik podał (co jest również zgodne z intuicją). |
|
GolemXIV |
» 2015-01-04 14:19:30 @antonio: dziwne że jest błąd bo takie zadania dostaliśmy od prowadzącego |
Proponuję założyć, że na tym forum też znajdziesz kilku profesjonalistów. Tyle tylko, że nie wiesz jaki mają tytuł naukowy albo inne osiągnięcia. Poziom wielu odpowiedzi wskazuje na [co najmniej niezłe] kompetencje. @kaikso: "U mnie działa" nie jest dobrą miarą poprawności. Bardzo podobne dyskusje, i wiele zmian w kodzie dotyczących walidacji i interpretacji wyników pośrednich miało miejsce przy tworzeniu boost::filesystem. W skrócie i uproszczeniu: jaka jest pełna nazwa katalogu: /a/.. ? Zazwyczaj / , ale jeśli filesystem dopuszcza linki (twarde albo miękkie), i /a jest takim linkiem, to może być inaczej. Na podstawie statycznej kontemplacji nazwy nic nie jest pewne (choć z praktyki wynika, że zazwyczaj jest dobrze). Tak samo tutaj: zazwyczaj (tekst - 1) siedzi w tej samej przestrzeni adresowej (filesystem nie ma linków) albo nie jest walidowany (nikt nie patrzy, co naprawdę znaczy "tekst-1"), to całość zadziała zgodnie ze statyczną kontemplacją wzoru. Zazwyczaj kompilator generuje kod taki, żeby jednak niespodzianki nie robić. Ale nie musi. |
|
Kaikso |
» 2015-01-04 21:43:10 Czyli kompilator wg standardu powinien wykonać takie obliczenia:
char tekst[] = "abc"; char * ptr = tekst; ptr = ptr - 1; ptr = ptr + strlen( tekst );
Czyli zachowanie jest de-facto niezdefiniowane, bo wskaźnik wychodzi poza zakres tablicy. |
Standard C uważa wyrażenie array[ - 1 ] za niezdefiniowane, ponieważ wartość pod tym adresem jest nie określona lub adres jest poza dopuszczalnymi granicami. Więc aby to było niezdefiniowane zachowanie należało by wykonać operację na owym adresie, więc gdybyśmy wykonali operację ptr = & array[ - 1 ]; kompilator mógłby wygenerować kod który najpierw odczytuje wartość z pod podanego adresu (niezdefiniowane zachowanie), a osobno podać adres określonego elementu. Ale jeśli operujemy jedynie na wartości samego wskaźnika tj. bez użycia operatorów pobrania wartości z tablicy lub wyłuskania nie możliwa jest sytuacja w której ten kod spowoduje wystąpienie niezdefiniowanego zachowania. PS. http://c-faq.com/aryptr/non0based.html opisuje kod w którym jest użyty operator pobrania wartości z tablicy (możliwe wystąpienie UB), a następnie pobrania adresu tej wartości, otrzymany adres pozostaje w stanie nie określonym (dalsze operacje na nim mogą spowodować UB). |
|
GolemXIV |
» 2015-01-04 22:39:44 Był kiedyś taki archaiczny procesor 8086 (i jego bliscy kuzyni, od 8088 aż do 80286). Adresowanie pamięci w nim było cokolwiek skomplikowane - to co znamy jako liniowe adresowanie to był model "huge", wcale nie defaultowy, bo zmuszał procesor do nadzwyczajnego wysiłku dla symulowania liniowej adresacji. Programy użytkownika były odpalane w ring-2, a nad wszystkim czuwał OS (w ring-0). W tych prehistorycznych czasach nawet nie można było porównywać wskaźników, nawet w relacji równe/nierówne, bo wyniki były ... nieokreślone :) Jeśli "tablica" leżała na samym brzegu segmentu (offset 0), to arytmetyka z podanego przykładu mogła pobudzić supervisora do działania.
|
|
DejaVu |
» 2015-01-05 09:46:08 Ale jeśli operujemy jedynie na wartości samego wskaźnika tj. bez użycia operatorów pobrania wartości z tablicy lub wyłuskania nie możliwa jest sytuacja w której ten kod spowoduje wystąpienie niezdefiniowanego zachowania.
|
No proszę Cię... przeczytaj przytoczone cytaty ze standardu, a nie tu cały czas własną teorię wygłaszasz. Standard mówi 'niezdefiniowane zachowanie' i koniec. W przytoczonych fragmentach tekstu jest mowa tylko i wyłącznie o poprawności obliczania wskaźnika, a nie o jakiejś tam dereferencji na którą się powołujesz. |
|
1 2 3 4 5 6 « 7 » 8 |