การติดตั้งวงเล็บมุมของ GCC รวมถึง ทำไมต้องอธิบายตามด้านล่าง?


11

เอกสารนี้ในส่วนที่2.6 คำนวณรวมมีย่อหน้าต่อไปนี้:

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

ฉันรู้ว่านี่เป็นการกำหนดการนำไปใช้ แต่ทำไมต้องเป็นเช่นนี้สำหรับ GCC ฉันหมายถึงเฉพาะประโยคที่เน้นสีด้านบน

แก้ไข

ฉันเพิ่งสังเกตเห็นว่าย่อหน้าที่สามก่อนที่จะยกมาข้างต้นกล่าวว่าต่อไปนี้:

คุณต้องระวังเมื่อคุณกำหนดแมโคร #defineบันทึกโทเค็นไม่ใช่ข้อความ ตัวประมวลผลล่วงหน้าไม่มีทางรู้ได้ว่าแมโครจะถูกใช้เป็นอาร์กิวเมนต์#includeดังนั้นจึงสร้างโทเค็นสามัญไม่ใช่ชื่อส่วนหัว สิ่งนี้ไม่น่าจะทำให้เกิดปัญหาหากคุณใช้เครื่องหมายคำพูดคู่ซึ่งรวมถึงค่าคงที่ของสตริง ถ้าคุณใช้วงเล็บมุม แต่คุณอาจมีปัญหา

ไม่มีใครรู้ว่าปัญหาแบบไหนที่ชี้ให้เห็นที่นี่?


6
สิ่งที่ดีที่สุดก็คือผู้พัฒนา GCC คิดว่าการมีช่องว่างท้ายชื่อไฟล์นั้นเป็นสิ่งที่น่ารังเกียจ
user3386109

1
ชื่อไฟล์ที่มีช่องว่างนำหน้าและ / หรือส่วนท้ายนั้นค่อนข้างดีในการใช้งานโดยเฉพาะบน Windows
Remy Lebeau

1
เพียงเพราะมันถูกกำหนดเช่นนั้นไม่ได้แปลว่ามันจะต้องถูกนิยามเช่นนั้น มันไม่ได้รับคำสั่งตามมาตรฐาน
eerorika

Visual Studio จะลบทั้งพื้นที่เริ่มต้นและสิ้นสุดดังนั้นจึงมีพฤติกรรมแตกต่างกัน HP aCC ทำตัวเหมือน gcc (อาจเป็นเพราะเหตุผลด้านความเข้ากันได้)
Slimak

บางครั้งเอกสารอธิบายอย่างง่าย ๆ ว่าเกิดอะไรขึ้นกับรหัสแทนที่จะเป็นอย่างอื่นโดยเฉพาะอย่างยิ่งในกรณีที่ไม่สำคัญ (คุณสามารถใช้พื้นที่ใดก็ได้ถ้าคุณใช้เครื่องหมายคำพูดคู่)
rustyx

คำตอบ:


8

ฉันเดาว่าตัวดำเนินการเลือกวิธีที่ง่ายที่สุดเมื่อพวกเขาใช้ฟังก์ชันนี้โดยไม่คิดมาก

ดูเหมือนว่าการติดตั้งครั้งแรกจะเกิดขึ้นในปี 2000-07-03 (เมื่อสองทศวรรษก่อน) ส่วนที่เกี่ยวข้องดูเหมือนว่า ( แหล่งที่มา ):

  for (;;)
    {
      t = cpp_get_token (pfile);
      if (t->type == CPP_GREATER || t->type == CPP_EOF)
        break;

      CPP_RESERVE (pfile, TOKEN_LEN (t));
      if (t->flags & PREV_WHITE)
        CPP_PUTC_Q (pfile, ' ');
      pfile->limit = spell_token (pfile, t, pfile->limit);
    }

โดยเฉพาะอย่างยิ่งมันแบ่งออกเมื่อเห็นCPP_GREATERโทเค็น (เช่น>) ก่อนสำรองหน่วยความจำสำหรับโทเค็น สิ่งนี้สมเหตุสมผลเนื่องจากไม่จำเป็นต้องจัดสรรหน่วยความจำเมื่อโทเค็นจะไม่ถูกเขียนลงในบัฟเฟอร์

จากนั้นหลังจากหน่วยความจำถูกจองแล้วตัวประมวลผลล่วงหน้าจะตรวจสอบว่าโทเค็นนั้นมีช่องว่างก่อนหน้า ( t->flags & PREV_WHITE) หรือไม่และเมื่อใดให้เขียนอักขระช่องว่างลงในบัฟเฟอร์

ดังนั้นใน< foo / bar >จะมีเพียงช่องว่างก่อนหน้าfoo(นั่นคือหลังจากเริ่มต้น<) /และbarถูกเก็บไว้


ยอดเยี่ยมคำตอบที่ดี นี่เป็นครั้งแรกที่ฉันมีโอกาสเห็นรหัสชิ้นส่วนใน GCC ขอบคุณสำหรับสิ่งนี้.
Ayrosa

แต่ไม่ใช่ในกรณีที่เงื่อนไขif (t->flags & PREV_WHITE) CPP_PUTC_Q (pfile, ' ');ขัดแย้งกับสิ่งที่ถูกกล่าวในเอกสาร: "ช่องว่างใด ๆ ระหว่างโทเค็นจะถูกลดขนาดลงในที่เดียว; ... "?
Ayrosa
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.