เหตุใดผู้คนจึงใช้ __ (ขีดล่างสองเท่า) ใน C ++ มาก


93

ฉันกำลังดูโค้ด C ++ โอเพนซอร์สและสังเกตเห็นคะแนนสองเท่าที่ใช้ในโค้ดส่วนใหญ่อยู่ที่จุดเริ่มต้นของชื่อตัวแปร

return __CYGWIN__;

แค่สงสัยว่ามีเหตุผลนี้หรือเป็นเพียงบางคน code style? ฉันจะคิดว่าฉันทำให้มันยากที่จะอ่าน


2
ทำไมอ่านยาก? ออกแบบมาโดยส่วนใหญ่เป็นเส้นคั่นเช่นเดียวกับเครื่องหมายคำพูด อย่างที่ฉันจำได้ส่วนใหญ่จะใช้สำหรับค่าคงที่ในตัว
Matthew Scharley

1
ไม่ไม่ใช่ตัวคั่น ขีดล่างใช้เพื่อแยกแยะชื่อที่สงวนไว้สำหรับการนำไปใช้งานจากชื่อที่ซอร์สโค้ดของผู้ใช้สามารถใช้ได้ ผู้ใช้สามารถทำได้#define FOO 1แต่ต้องไม่ทำ#define __FOO__ 1ดังนั้นการใช้งานจึงมีอิสระที่จะใช้ชื่อ__FOO__สำหรับมาโครตัวแปรฟังก์ชันและอื่น ๆ ของตัวเอง
Jonathan Wakely

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

คำตอบ:


128

จากการเขียนโปรแกรมใน C ++ กฎและคำแนะนำ :

การใช้เครื่องหมายขีดล่าง ("__ ') สองอันในตัวระบุสงวนไว้สำหรับการใช้งานภายในของคอมไพเลอร์ตามมาตรฐาน ANSI-C

เครื่องหมายขีดล่าง (`_ ') มักใช้ในชื่อของฟังก์ชันไลบรารี (เช่น" _main "และ" _exit ") เพื่อหลีกเลี่ยงการชนกันอย่าขึ้นต้นตัวระบุด้วยเครื่องหมายขีดล่าง


1
คู่มือนั้นดูเหมือนจะเขียนขึ้นก่อนที่จะnamespaceได้รับการแนะนำ
cz

นอกจากนี้ยังมาจากวิทยาลัยอิมพีเรียลลอนดอนไม่ได้มาจากมาตรฐาน C ++ อาจเป็นข้อเสนอแนะที่ดี
stucash

1
@cz Namespaces ไม่เกี่ยวข้อง _mainส่วนหัวของระบบสามารถกำหนดชื่อแมโครที่เริ่มต้นด้วยการขีดเช่น
martinkunev

ตัวระบุที่เริ่มต้นด้วยขีดล่างเดียวจะสงวนไว้ในเนมสเปซส่วนกลางเท่านั้นในขณะที่ตัวระบุที่ขึ้นต้นด้วยขีดล่างเดียวที่เขียนด้วยตัวอักษรตัวพิมพ์ใหญ่จะสงวนไว้เช่นเดียวกับตัวระบุใด ๆ ที่มีขีดล่างคู่ที่ใดก็ได้ ข้อมูลนี้อ้างอิงจากcppreference.com
WARhead

50

เว้นแต่พวกเขารู้สึกว่าเป็น "ส่วนหนึ่งของการนำไปใช้" นั่นคือไลบรารีมาตรฐานก็ไม่ควร

กฎมีความเฉพาะเจาะจงพอสมควรและมีรายละเอียดมากกว่ากฎอื่น ๆ เล็กน้อย

ตัวระบุทั้งหมดที่มีขีดล่างคู่หรือขึ้นต้นด้วยขีดล่างตามด้วยอักษรตัวพิมพ์ใหญ่จะสงวนไว้สำหรับการใช้งานในทุกขอบเขตกล่าวคืออาจใช้สำหรับมาโคร

นอกจากนี้ตัวระบุอื่น ๆ ทั้งหมดที่ขึ้นต้นด้วยขีดล่าง (เช่นไม่ตามด้วยขีดล่างหรืออักษรตัวพิมพ์ใหญ่อื่น) จะถูกสงวนไว้สำหรับการนำไปใช้งานในขอบเขตส่วนกลาง ซึ่งหมายความว่าคุณสามารถใช้ตัวระบุเหล่านี้ในเนมสเปซของคุณเองหรือในนิยามคลาส

นี่คือเหตุผลที่ Microsoft ใช้ชื่อฟังก์ชันที่มีขีดล่างนำหน้าและทั้งหมดเป็นตัวพิมพ์เล็กสำหรับฟังก์ชันไลบรารีรันไทม์หลักจำนวนมากซึ่งไม่ได้เป็นส่วนหนึ่งของมาตรฐาน C ++ ชื่อฟังก์ชันเหล่านี้รับประกันว่าจะไม่ขัดแย้งกับฟังก์ชัน C ++ มาตรฐานหรือฟังก์ชันรหัสผู้ใช้


1
ใน C ++ ฉันเห็นเฉพาะ [lex.name] และสำหรับชื่อส่วนกลาง [global.names] คุณสามารถให้ข้อมูลอ้างอิงได้หรือไม่? ขอบคุณ
a.lasram

36

ตามมาตรฐาน C ++ ตัวระบุที่ขึ้นต้นด้วยขีดล่างหนึ่งถูกสงวนไว้สำหรับไลบรารี ตัวระบุที่ขึ้นต้นด้วยขีดล่างสองตัวสงวนไว้สำหรับผู้จำหน่ายคอมไพเลอร์


18
ยิ่งไปกว่านั้น: ตัวระบุที่มีขีดล่างคู่ที่ใดก็ได้ในนั้นจะถูกสงวนไว้ 17.4.3.1.2
Steve Jessop

ใน C ++ ฉันเห็นเฉพาะ [lex.name] และสำหรับชื่อส่วนกลาง [global.names] คุณสามารถให้ข้อมูลอ้างอิงได้หรือไม่? ขอบคุณ
a.lasram

10

ความเห็นข้างต้นถูกต้อง __Symbol__โดยทั่วไปแล้วโทเค็นวิเศษที่จัดหาโดยผู้จำหน่ายคอมไพเลอร์ (หรือตัวประมวลผลล่วงหน้า) ที่เป็นประโยชน์ บางทีสิ่งที่ใช้กันอย่างแพร่หลายคือ__FILE__และ__LINE__ซึ่งขยายโดยตัวประมวลผลล่วงหน้า C เพื่อระบุชื่อไฟล์และหมายเลขบรรทัดปัจจุบัน มีประโยชน์เมื่อคุณต้องการบันทึกความล้มเหลวในการยืนยันโปรแกรมบางประเภทรวมถึงตำแหน่งที่เป็นข้อความของข้อผิดพลาด


8

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


4

ขีดล่างสองอันสงวนไว้สำหรับการนำไปใช้งาน

คำตอบที่ได้รับการโหวตสูงสุดอ้างอิงการเขียนโปรแกรมใน C ++: กฎและคำแนะนำ :

"การใช้เครื่องหมายขีดล่าง (` __ ') สองอันในตัวระบุสงวนไว้สำหรับการใช้งานภายในของคอมไพเลอร์ตามมาตรฐาน ANSI-C "

อย่างไรก็ตามหลังจากที่อ่านไม่กี่ C ++ และมาตรฐาน C ผมก็ไม่สามารถที่จะหาการเอ่ยถึงขีดใด ๆ จะถูก จำกัด ให้เพียงแค่การใช้งานภายในของคอมไพเลอร์ มาตรฐานทั่วไปเพิ่มเติมสำรองขีดคู่สำหรับการดำเนินการ

C ++

C ++ (ร่างการทำงานปัจจุบันเข้าถึง 2019-5-26) ในlex.name:

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

แม้ว่าคำถามนี้เป็นคำถามเฉพาะสำหรับ C ++ แต่ฉันได้อ้างถึงส่วนที่เกี่ยวข้องจากมาตรฐาน C 99 และ 17:

C99ส่วน 7.1.3

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

C17พูดเช่นเดียวกับ C99

อะไรคือการดำเนินการ ?

สำหรับ C / C ++ การนำไปใช้อย่างหลวม ๆ หมายถึงทรัพยากรชุดที่จำเป็นในการสร้างไฟล์ปฏิบัติการจากไฟล์ต้นทางของผู้ใช้ ซึ่งรวมถึง:

  • พรีโปรเซสเซอร์
  • คอมไพเลอร์
  • ลิงค์เกอร์
  • ห้องสมุดมาตรฐาน

ตัวอย่างการใช้งาน

มีจำนวนที่แตกต่างกัน c ++ การใช้งานที่กล่าวถึงในที่มีวิกิพีเดีย (ไม่มีลิงก์จุดยึด, ctrl + f "การใช้งาน")

นี่คือตัวอย่างของการใช้งาน C / C ++ ของ Digital Mars โดยสงวนคำหลักบางคำไว้สำหรับคุณลักษณะของคำเหล่านั้น


3

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

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

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