Neden i ++; ben--; birbiri ardına?


164

1997 yılında yayımlanan nmap için kaynak koduna bakıyordum ve bana biraz garip görünen kodun bu bölümünü fark ettim:

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';

Neden birbirinize i++;ve i--;sonra birbirinize kavuştunuz? iolduğu 0, daha sonra i++döner ietmek 1. Bundan sonra, i--döner ietmek 0.

Orijinal kaynak koduna bağlantı. Aramak:

i++;
i--;

Herkes bunun ne için olduğunu açıklayabilir mi?


25
Yazara sorun .
DaBler

8
Sanırım yazar daha sonra kaldırmayı unuttuğu bazı deneysel veya hata ayıklama kodlarının bir parçasıydı.
Nate Eldredge

6
Nedeni sizi şaşırtmaktır, tek amaç budur :-) Bunun eski bir derleyicide bazı derleyici hatalarının etrafında çalışması için küçük bir şans var, bu durumda bize bu nedeni anlatan bir yorum olmalı.
gnasher729

18
@ RingØ: Eğlence için 1988'de gcc 1.27 ile godbolt'da denedim: godbolt.org/z/yYyFrQ . (Modern sistem başlıkları ile çalışmaz, bu yüzden tüm standart kütüphane işlevlerini kendim beyan etmek zorunda kaldım.) Ama -Ogerçekten bu ifadeleri optimize ediyor.
Nate Eldredge

21
Bu, programcının hat tarafından ödendiği anlamına gelir ...
TonyK

Yanıtlar:


152

Bu bir hataydı. Bu çizgiler birlikte ideğişmeden sonuçlanır , bu yüzden orada olmamalıydılar.

Nmap'ı tanıtan bağlantılı makale 1 Eylül 1997'de yayınlanmıştır. Https://svn.nmap.org/nmap adresindeki nmap için SVN deposuna bakarsanız, 10 Şubat 1998'de kontrol edilen ilk düzeltme şu satırlara sahip değildir:

int i=0, j=0,start,end;
char *expr = strdup(origexpr);
char *mem = expr;

ports = safe_malloc(65536 * sizeof(short));
for(;j < exlen; j++) 
  if (expr[j] != ' ') expr[i++] = expr[j]; 
expr[i] = '\0';

Bu, yazarın ilk nmap kaynak kodunu ve SVN'ye ilk check-in'i yayınlama arasında bulduğu ve sabitlediği bir şeydir.


1
Hmm bu sayfada <pre>makalenin etrafında da etiketler eksik ; Chrome'un müfettişi, bunun DOM inşaatı sırasında bazı belge yönetimine nasıl yol açtığını ortaya koyuyor;)
Asteroids with Wings

4
Tamamen istenmeyen okuyucuları karıştırır. Açıkça bir hata olduğunu söyleyebilirim. ;-)
sergut

2
@sergut Wikipedia seninle aynı fikirde değil, ama bu blog yazısı aynı fikirde ve ben de eğilimliyim :-)
Toivo Säwén

4
Eğer ibir int olmasaydı , operatör aşırı yükleri olan bazı süslü bir sınıf olsaydı , (olası ve genellikle kötü kodlama uygulamalarının bir işareti olsa da) bunun bazı yan etkileri olabilir. (Sadece bu tabii ki C ++ olsaydı geçerlidir.)
Darrel Hoffman

5
Belki bazı bağlamlarda (bellek eşlemeli G / Ç) bir değişkeni değiştirmenin harici etkileri olabileceğini belirtmek gerekir.
nullromo

40

Bunun faydası yok. Kesinlikle hiçbir şey yapmaz.

Tahmin edersem, muhtemelen geliştirme sırasında kullanılan bazı hata ayıklama kodlarının kalıntılarıdır.

Ben ikisinden biri olduğunu tahmin ediyorum i++ya i--bir değişiklik tanıtıldı ve diğer başka tanıtıldı.

Başlangıç ​​noktasını bulmak için bir yolum yok, çünkü ilk kaynak sürümü ile ilk SVN revizyonu arasında revizyon geçmişi yoktu.


14
Kod hata ayıklama hakkında spekülasyon doğru olduğunu düşünüyorum. Ben sadece onları beklediğiniz yerde kesme noktaları almak için çok farklı tür hata ayıklama kodu gördüm.
Nathan Goings

9

Optimize edici olmayan bir derleyici veya donanım yan etkilerini tanıyan bir derleyici için i ++; i-- sekansı, for döngüsünden alınan ve eğer iç içe yerleştirilen yoldan bağımsız olarak i'nin bellekten okunmasına, sonra yeniden yazılmasına neden olur.

Paralel işlemede, bazen bir kod dizisinin global kopyalar yerine kendi yerel değişken kopyalarını kullanmasını sağlamak için derleyici saldırıları alınır.

Örnek bir kod snippet'i olduğundan, kullanılan derleyici, beklenen işletim sistemi / donanım veya bunun bağımsız bir iş parçacığı olarak yürütülmesi mümkün olan bir kod dizisi / işlevinde olup olmadığı belirlenemez.

Daha basit sistemlerde, geçici olarak hata ayıklama ortamında tuzak özelliğini kullanmak için değişkenlerde değişiklik yapmaya zorladım. Durum böyleyse, yazar geliştirme tamamlandığında kodu kaldırmayı unutmuş olabilir.


1
öyleyse neden sadece geçici olarak ilan etmiyorsunuz?
vsz

6
iYerel değişken olarak bildirimi yukarıdaki kodda gösterilmiştir ve i++; i--satırların bulunduğu noktada başka bir iş parçacığına erişilmesi mümkün değildir.
interjay

@vsz Bence onun iuçucu olmaya zorlandığı anlamına geliyor . Gerçi C veya C ++ ile iplik ile uğraşmadı, bu yüzden nasıl uçucu olarak tedavi edilebilir ve nasıl i++; i--bastırmak hiçbir ipucu var.
Egor Hans

uçucu ipliğin emniyet dışında başka amaçları da vardır. Hata ayıklama sırasında derleyicinin onu optimize etmemesini sağlamak için de kullanılabilir.
vsz

2

Sadece güncellenmiş kodu kontrol etmenizi öneririm. Hemen arkasından (i = 2 + 1) kullanırsanız (i-1) bu hiç mantıklı değil. İ'nin değeri değişmeden kalır. Herhangi bir c veya c ++ derleyicisini kullanarak deneyebilirsiniz. hatta başka bir dilde bile aynıdır. Yanlış veya doğru olup olmadığımı görmek için derleyicideki kodu çalıştırın ve yanlış cevap verip vermediğimi bana bildirin.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.