Patrzyłem na kod źródłowy nmap wydany w 1997 roku i zauważyłem ten fragment kodu, który wygląda mi trochę dziwnie:
int i=0, j=0,start,end;
char *expr = strdup(origexpr);
ports = safe_malloc(65536 * sizeof(short));
i++; /* <<<<<< */
i--; /* <<<<<< */
for(;j < exlen; j++)
if (expr[j] != ' ') expr[i++] = expr[j];
expr[i] = '\0';
Dlaczego miałbyś, i++;
a potem i--;
zaraz po sobie? i
jest 0
, a następnie i++
zmienia i
się w 1
. Potem i--
zwraca się i
do 0
.
Link do oryginalnego kodu źródłowego. Szukaj:
i++;
i--;
Czy ktoś może wyjaśnić, po co to jest?
-O
temu rzeczywiście optymalizują te instrukcje.Odpowiedzi:
To był błąd. Te linie razem powodują,
i
że pozostają niezmienione, więc nie powinny tam być.Powiązany artykuł, który wprowadził nmap, został opublikowany 1 września 1997 r. Jeśli spojrzysz na repozytorium SVN dla nmap na https://svn.nmap.org/nmap , wstępna wersja sprawdzona 10 lutego 1998 r. Nie zawiera następujących wierszy:
Jest to więc coś, co autor znalazł i naprawił między opublikowaniem początkowego kodu źródłowego nmap a początkowym zameldowaniem w SVN.
źródło
<pre>
tagów wokół artykułu; Inspektor Chrome ujawnia, w jaki sposób prowadzi to do zniekształcania niektórych dokumentów podczas budowy DOM;)i
nie była to int, ale jakaś wymyślna klasa z przeciążeniem operatora, możliwe jest (choć mało prawdopodobne i ogólnie oznaka złych praktyk kodowania), że może to mieć pewne skutki uboczne. (Dotyczy tylko, jeśli był to oczywiście C ++.)To jest bezużyteczne. Nie robi absolutnie nic.
Gdybym miał spekulować, to prawdopodobnie pozostałość kodu debugowania, który został użyty podczas programowania.
Zgaduję, że albo jeden
i++
alboi--
został wprowadzony w jednej zmiany, a druga została wprowadzona w drugim.Nie mam jednak sposobu, aby znaleźć punkt wprowadzenia, ponieważ nie było historii zmian między pierwszą wersją źródłową a pierwszą wersją SVN.
źródło
Dla nieoptymalizującego kompilatora lub takiego, który rozpoznaje sprzętowe skutki uboczne, i ++; Sekwencja i spowoduje, że i zostanie odczytany z pamięci, a następnie ponownie zapisany, bez względu na ścieżkę przechodzącą przez pętlę for i zagnieżdżoną, jeśli.
W przetwarzaniu równoległym czasami wykorzystuje się włamania kompilatora, aby zapewnić, że sekwencja kodu używa własnych lokalnych kopii zmiennych zamiast kopii globalnych.
Ponieważ przykładem jest fragment kodu, nie można określić używanego kompilatora, oczekiwanego systemu operacyjnego / sprzętu ani tego, czy jest to sekwencja / funkcja kodu, którą można wykonać jako niezależny wątek.
W prostszych systemach tymczasowo zmusiłem zmiany zmiennych, aby korzystały z funkcji pułapki w środowisku debugowania. Gdyby tak było, autor mógł zapomnieć o usunięciu kodu po zakończeniu programowania.
źródło
i
zmiennej lokalnej jest pokazana w powyższym kodzie i nie ma możliwości uzyskania dostępu do niej przez inny wątek w punkcie, w którym znajdują sięi++; i--
linie.i
ma na myśli, że musi być nieulotny. Nie zajmowałem się wątkami w C lub C ++, więc nie mam pojęcia, jak można to potraktować jako niestabilne i jaki++; i--
by to stłumić.Zasugeruję sprawdzenie tylko zaktualizowanego kodu. Jeśli użyjesz (i = 2 + 1) zaraz po tym (i-1), to nie ma sensu. Wartość i pozostaje niezmieniona. Możesz spróbować za pomocą dowolnego kompilatora c lub c ++. lub nawet w innym języku jest to samo. Uruchom kod w kompilatorze, aby sprawdzić, czy się mylę, czy mam rację, i daj mi znać, jeśli udzielę złej odpowiedzi.
źródło