ทำไมต้อง i ++ ผม--; หลังจากแต่ละอื่น ๆ ?


164

ฉันกำลังดูซอร์สโค้ดสำหรับnmapที่เปิดตัวในปี 1997 และฉันสังเกตเห็นรหัสส่วนนี้ที่ดูแปลกสำหรับฉัน:

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

ทำไมคุณถึงมีi++;และi--;หลังจากนั้นกัน? iเป็น0แล้วi++จะเปลี่ยนไปi 1หลังจากนั้นi--จะเปลี่ยนไปi0

ลิงก์ไปยังซอร์สโค้ดต้นฉบับ ค้นหา:

i++;
i--;

ทุกคนสามารถอธิบายสิ่งนี้มีไว้เพื่ออะไร?


25
ถามผู้เขียน
DaBler

8
ฉันเดาว่าพวกเขาเป็นส่วนหนึ่งของรหัสการทดลองหรือการดีบักซึ่งผู้เขียนลืมที่จะลบหลังจากนั้น
Nate Eldredge

6
เห็นได้ชัดว่าเหตุผลที่ทำให้คุณสับสนนั่นคือจุดประสงค์เพียงอย่างเดียว :-) มีโอกาสเล็กน้อยที่จะสามารถแก้ไขข้อผิดพลาดของคอมไพเลอร์ในคอมไพเลอร์โบราณบางกรณีในกรณีนี้ควรมีความคิดเห็นที่บอกเหตุผลนี้
gnasher729

18
@ Ringo: เพื่อความสนุกสนานฉันพยายามกับ GCC 1.27 ประมาณปี 1988 ใน godbolt: godbolt.org/z/yYyFrQ (มันไม่ทำงานกับส่วนหัวของระบบที่ทันสมัยดังนั้นฉันจึงต้องประกาศว่าไลบรารีมาตรฐานทั้งหมดทำหน้าที่ตัวเอง) แต่ด้วยความที่-Oจริงแล้วมันเพิ่มประสิทธิภาพของคำสั่งเหล่านั้น
Nate Eldredge

21
หมายความว่าโปรแกรมเมอร์จ่ายเงินให้กับสาย ...
TonyK

คำตอบ:


152

นี่เป็นข้อผิดพลาด เส้นเหล่านี้เข้าด้วยกันทำให้iไม่มีการเปลี่ยนแปลงดังนั้นจึงไม่ควรอยู่ที่นั่น

บทความที่เชื่อมโยงที่แนะนำ nmap ได้รับการเผยแพร่เมื่อวันที่ 1 กันยายน 1997 หากคุณดูที่เก็บ SVN สำหรับ nmap ที่https://svn.nmap.org/nmapการแก้ไขเริ่มต้นที่เช็คอินในวันที่ 10 กุมภาพันธ์ 1998 จะไม่มีบรรทัดเหล่านั้น:

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

ดังนั้นนี่คือสิ่งที่ผู้เขียนพบและแก้ไขระหว่างการเผยแพร่ซอร์สโค้ด nmap เริ่มต้นและการเช็คอินเริ่มต้นไปที่ SVN


1
อืมหน้านั้นไม่มี<pre>แท็กอยู่รอบ ๆ บทความเช่นกัน ผู้ตรวจสอบของ Chrome แสดงให้เห็นว่าสิ่งที่นำไปสู่การสร้างเอกสารในระหว่างการก่อสร้าง DOM;)
Asteroids With Wings

4
มันทำให้ผู้อ่านสับสนซึ่งไม่ได้ตั้งใจอย่างสมบูรณ์ ฉันว่ามันเป็นข้อผิดพลาดอย่างชัดเจน ;-)
sergut

2
@sergut Wikipedia ไม่เห็นด้วยกับคุณ แต่โพสต์บล็อกนี้ทำและฉันก็อยากจะเช่นกัน :-)
Toivo Säwén

4
ตอนนี้ถ้าiไม่ได้เป็นคลาสที่น่าสนใจ แต่มีโอเปอเรเตอร์เกินพิกัดก็เป็นไปได้ (แต่ไม่น่าเป็นไปได้และโดยทั่วไปเป็นสัญญาณของการเข้ารหัสที่ไม่ดี) ซึ่งอาจมีผลข้างเคียงบางอย่าง (ใช้เฉพาะในกรณีนี้เป็น C ++ แน่นอน)
Darrel Hoffman

5
อาจจะน่าสังเกตว่าในบริบทบางอย่าง (IO หน่วยความจำที่แมป) การเปลี่ยนแปลงตัวแปรอาจมีผลกระทบภายนอก
nullromo

40

มันไร้ประโยชน์ มันไม่ทำอะไรเลยอย่างแน่นอน

ถ้าฉันจะคาดเดาอาจเป็นไปได้ว่าส่วนที่เหลือของรหัสการดีบักที่ใช้ระหว่างการพัฒนา

ฉันคาดเดาว่ามีการเปลี่ยนแปลงอย่างใดอย่างหนึ่งi++หรืออย่างใดอย่างหนึ่งi--ในการเปลี่ยนแปลงและอื่น ๆ ถูกนำมาใช้ในอีก

ฉันไม่มีวิธีที่จะหาจุดเริ่มต้น แต่เนื่องจากไม่มีประวัติการแก้ไขระหว่างการปล่อยซอร์สเริ่มต้นและการแก้ไข SVN ครั้งแรก


14
ฉันคิดว่าการเก็งกำไรเกี่ยวกับรหัสการดีบักนั้นถูกต้อง ฉันเห็นรหัสการดีบักที่แตกต่างกันมากมายเพื่อรับจุดพักที่คุณคาดหวัง
Nathan Goings

9

สำหรับคอมไพเลอร์ที่ไม่ทำให้เกิดประโยชน์สูงสุดหรือคอมไพเลอร์ที่รับรู้ผลข้างเคียงของฮาร์ดแวร์ i ++; ลำดับ i-- จะทำให้ i ถูกอ่านจากหน่วยความจำจากนั้นเขียนใหม่โดยไม่คำนึงถึงพา ธ ที่ผ่านสำหรับลูปและซ้อนกันถ้า

ในการประมวลผลแบบขนานบางครั้งแฮ็กคอมไพเลอร์ถูกนำมาใช้เพื่อให้แน่ใจว่าลำดับรหัสใช้สำเนาโลคัลของตัวเองแทนที่จะเป็นสำเนาทั่วโลก

เนื่องจากตัวอย่างคือโค้ดขนาดหนึ่งจึงไม่สามารถกำหนดคอมไพเลอร์ที่ใช้ระบบปฏิบัติการ / ฮาร์ดแวร์ที่คาดหวังหรือไม่ว่าจะอยู่ในลำดับรหัส / ฟังก์ชั่นที่เป็นไปได้ที่จะดำเนินการเป็นเธรดอิสระ

ในระบบที่ง่ายกว่านี้ฉันได้บังคับให้เปลี่ยนแปลงตัวแปรชั่วคราวเพื่อใช้คุณสมบัติแทร็บในสภาพแวดล้อมการดีบัก หากเป็นกรณีนี้ผู้เขียนอาจลืมลบรหัสเมื่อการพัฒนาเสร็จสมบูรณ์


1
ถ้าเช่นนั้นทำไมไม่ประกาศว่ามันระเหย?
vsz

6
การประกาศiว่าเป็นตัวแปรโลคัลถูกแสดงในโค้ดด้านบนและไม่มีวิธีที่สามารถเข้าถึงได้โดยเธรดอื่น ณ จุดที่มีi++; i--บรรทัด
ระหว่าง

@ vsz ฉันคิดว่าเขาหมายถึงiถูกบังคับให้ไม่เปลี่ยนแปลง ฉันยังไม่ได้จัดการกับเธรดใน C หรือ C ++ ดังนั้นฉันจึงไม่มีเงื่อนงำว่ามันจะเป็นความผันผวนได้อย่างไรและi++; i--จะระงับอย่างไร
Egor Hans

สารระเหยมีวัตถุประสงค์อื่นนอกเหนือจากความปลอดภัยของด้าย นอกจากนี้ยังสามารถใช้ในขณะที่การดีบักเพื่อให้แน่ใจว่าคอมไพเลอร์จะไม่ปรับให้เหมาะสม
vsz

2

ฉันจะแนะนำให้คุณตรวจสอบรหัสที่อัปเดตเท่านั้น หากคุณใช้ (i = 2 + 1) หลังจากนั้น (i-1) ที่ไม่สมเหตุสมผล ค่าของฉันยังคงไม่เปลี่ยนแปลง คุณสามารถลองใช้คอมไพเลอร์ c หรือ c ++ หรือแม้แต่ในภาษาอื่นมันก็เหมือนกัน เรียกใช้รหัสในคอมไพเลอร์เพื่อดูว่าฉันผิดหรือถูกและแจ้งให้ฉันทราบหากฉันให้คำตอบที่ผิด

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.