Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> C++

แอตทริบิวต์ (Attributes) ใน C++


แอตทริบิวต์ (Attributes) เป็นวิธีสมัยใหม่ใน C++ เพื่อทำให้โค้ดมาตรฐาน หากโค้ดรันบนคอมไพลอร์ต่างกัน Attributes ใช้ให้ข้อมูลเพิ่มเติมที่ใช้บังคับ เงื่อนไข (constraints), เพิ่มประสิทธิภาพ (optimization) และสร้างโค้ดเฉพาะ (specific code generation) หากจำเป็น

เหมือนคู่มือข้อมูลสำหรับคอมไพลอร์ เพื่อบังคับบางอย่างที่จะเพิ่มประสิทธิภาพของโค้ด Attributes ปรากฏครั้งแรกใน C++11 และเป็นส่วนสำคัญของภาษาโปรแกรมมาจนถึงปัจจุบัน นอกจากนี้ ทุกเวอร์ชันจะมีการปรับปรุงต่อเนื่องเพื่อทำให้มีพลังมากขึ้นและดีขึ้น

วิธีการกำหนด Attributes ใน C++

สำหรับ C++ เวอร์ชันต่างๆ ไวยากรณ์ในการกำหนด attributes จะต่างกัน

ไวยากรณ์สร้าง attribute ใน C++11:

[[attribute-list]]

ไวยากรณ์สร้าง attribute ใน C++17:

[[using attribute-namespace : attribute_list]]

ไวยากรณ์สร้าง attribute ใน C++20 (จะเผยแพร่เร็วๆ นี้):

[[contract-attriubute-token contract-level-identifier : expression]]

คุณสามารถใช้ attributes หลายตัวกับตัวแปร ฟังก์ชัน คลาสได้

ตอนนี้เรารู้แล้วว่า attributes คืออะไร ทำงานอย่างไร และกำยังไง มาดู attributes มาตรฐานที่มีใน C++ กัน

Attributes ที่เพิ่มใน C++11

noreturn - ใช้บอกคอมไพลอร์ว่าฟังก์ชันนี้ไม่คืนค่าใดๆ

Syntax

[[noreturn]]

ตัวอย่าง

[[noreturn]] void f();

ฟังก์ชันนี้จะไม่คืนค่า ไม่ว่าจะเป็น void ก็ตาม

Attribute noreturn เมื่อใช้ใน C++ จะทำให้คอมไพลอร์แจ้งเตือน (warning) หากมีบางอย่างผิดพลาดและโฟลว์ไม่กลับไปยังโค้ดที่เรียก เช่น กรณี infinite loop หรือ error

carries_dependency - ใช้กำหนด dependencies ทั้งหมดที่อยู่ใน release-consume และอนุญาตให้คอมไพลอร์เพิ่มประสิทธิภาพโดยไม่ผ่านคำสั่งที่ใช้หน่วยความจำไม่จำเป็น

Syntax

[[carries_dependency]]

ใช้หลักกับการประกาศฟังก์ชันหรือพารามิเตอร์เพื่อประกาศ dependencies

deprecated - ใช้กำหนด entity ที่ deprecated ในโค้ด การใช้ entity ที่ deprecated นี้ ยอมรับได้แต่ ไม่แนะนำ ให้ใช้

Syntax

[[deprecated]]
[[deprecated (reason)]]

reason คือ สตริงที่ให้เหตุผลว่าทำไมถึง deprecated และให้ทางเลือกแทนสำหรับ entity ที่ deprecated

Entities ที่สามารถ deprecated ได้ ได้แก่ คลาส โครงสร้าง (structure) ยูเนียน (union) typedef-name สมาชิก static ฟังก์ชัน namespace การแจกแจง (enumeration)

fallthrough - ใช้บอกคอมไพลอร์ว่า fallthrough ไปยัง case ถัดไปเป็นเจตนาโดยเจตนารับรู้ ทำให้คอมไพลอร์ไม่เตือน fallthrough

Syntax

[[fallthrough]]

fallthrough อาจใช้ได้กับ switch เท่านั้น เนื่องจาก case ถัดไปถูกกำหนดไว้สำหรับมัน

nodiscard - ใช้สำหรับฟังก์ชันที่จะคืนค่า enumeration จะถูกเรียกจาก discarded value expression แทนการ cast เป็น void call คอมไพลอร์จะแจ้งเตือนสำหรับมันด้วย

Syntax

[[nodiscard]]
[[nodiscard (reason)]] (เพิ่มใน C++20)

reason คือ สตริงที่ใช้ให้เหตุผลว่าทำไมไม่ควร discard ผลลัพธ์ และจะรวมอยู่ใน C++20

maybe_unused - ใช้บอกคอมไพลอร์ให้ปิดกั้นหรือกำจัด warning ที่แสดงในกรณีของ entities ที่ไม่ได้ใช้

Syntax

[[maybe_unused]]

Entities ที่สามารถประกาศ maybe_unused ได้ ได้แก่ คลาส โครงสร้าง ยูเนียน typedef-name สมาชิก static ฟังก์ชัน ตัวแปร การแจกแจง

likely, unlikely - ใช้กำหนดว่าเส้นทางทางเลือก (alternative path) มีโอกาสมากกว่าหรือน้อยกว่าเส้นทางการทำงานปัจจุบัน

Syntax

[[likely]]
[[unlikely]]

โดยทั่วไปจะนำไปใช้กับ entities ที่เปลี่ยนโฟลว์ของโปรแกรม เช่น labels และ statements

no_unique_address - ใช้กำหนด data-member ที่ไม่จำเป็นต้องมีที่อยู่เฉพาะ ใช้โดยทั่วไปในกรณีของ non-static data members ที่การจัดสรรหน่วยความจำไม่จำเป็น

Syntax

[[no_unique_address]]

มีประโยชน์เมื่อคอมไพลอร์ต้องกำหนดตำแหน่งหน่วยความจำระหว่างตัวแปรปกติและ no_unique_address คอมไพลอร์จะให้ความสำคัญกับตัวแรก

optimize_for_synchronized - ใช้กำหนดว่านิยามของฟังก์ชันที่กำหนดต้องเพิ่มประสิทธิภาพสำหรับการเรียกใช้จาก synchronized statement

Syntax

[[optimize_for_synchronized]]

ฟังก์ชันที่กำหนดเป็น optimize_for_synchronized จะหลีกเลี่ยงการ serialize synchronized blocks

expects - ระบุเงื่อนไขที่จำเป็นสำหรับอาร์กิวเมนต์ของฟังก์ชัน เพื่อให้ฟังก์ชันทำงานได้

Syntax

[[expects : condition]]

condition กำหนดเงื่อนไขที่ต้องเป็นจริงเพื่อให้ฟังก์ชันทำงานได้

นี่คือ attributes ทั้งหมดที่กำหนดใน C++ ตั้งแต่ C++11 ถึง C++20 ตอนนี้มาดูว่า ทำไม attributes ถึงถูกใช้ในการเขียนโปรแกรม คือ attributes ที่เสนอแก้ปัญหาอะไร?

  • เพิ่มเงื่อนไขให้โค้ด - ในหลายกรณี attributes เพิ่มความหมายให้โค้ด ทำให้มันถูกต้องมากขึ้นและลดความพยายามเพิ่มเติม

  • ให้ข้อมูลการเพิ่มประสิทธิภาพเพิ่มเติมแก่คอมไพลอร์ - บาง attributes เช่น fallthrough, likely, maybe_unused ให้ข้อมูลแก่คอมไพลอร์เพื่อทำ optimization เฉพาะ

  • หลีกเลี่ยง warning และ errors - บางครั้งตรรกะของโปรแกรมเมอร์ขัดกับกติกาที่เข้มงวดของ C++ นี่คือกรณีที่บาง attributes ช่วยให้ผู้ใช้หลีกเลี่ยงหรือปิดกั้น warning ที่จะเกิดขึ้น