C ++ 17 [[nodiscard]]
C ++ 17 สร้างมาตรฐาน "ธุรกิจที่ถูกละเว้น" ด้วยแอตทริบิวต์
ดังนั้นฉันหวังว่าการใช้งานที่เป็นไปตามข้อกำหนดจะเตือนเมื่อ nodiscard
มีการให้เท่านั้นและจะไม่เตือนเป็นอย่างอื่น
ตัวอย่าง:
main.cpp
[[nodiscard]] int f() {
return 1;
}
int main() {
f();
}
รวบรวม:
g++ -std=c++17 -ggdb3 -O0 -Wall -Wextra -pedantic -o main.out main.cpp
ผล:
main.cpp: In function ‘int main()’:
main.cpp:6:6: warning: ignoring return value of ‘int f()’, declared with attribute nodiscard [-Wunused-result]
6 | f();
| ~^~
main.cpp:1:19: note: declared here
1 | [[nodiscard]] int f() {
|
สิ่งต่อไปนี้หลีกเลี่ยงคำเตือน:
(void)f();
[[maybe_unused]] int i = f();
ฉันไม่สามารถใช้งานmaybe_unused
ได้โดยตรงในการf()
โทร:
[[maybe_unused]] f();
ให้:
main.cpp: In function ‘int main()’:
main.cpp:6:5: warning: attributes at the beginning of statement are ignored [-Wattributes]
6 | [[maybe_unused]] f();
| ^~~~~~~~~~~~~~~~
การ(void)
ทำงานของนักแสดงดูเหมือนจะไม่บังคับ แต่ได้รับการ "สนับสนุน" ในมาตรฐาน: ฉันจะทิ้งค่าส่งคืน [[nodiscard]] โดยเจตนาได้อย่างไร
ตามที่เห็นในข้อความเตือน "วิธีแก้ไข" อย่างหนึ่งของคำเตือนคือการเพิ่ม-Wno-unused-result
:
g++ -std=c++17 -ggdb3 -O0 -Wall -Wextra -pedantic -Wno-unused-result -o main.out main.cpp
แม้ว่าฉันจะไม่แนะนำให้เพิกเฉยต่อคำเตือนทั่วโลกเช่นนี้
C ++ 20 ยังช่วยให้คุณสามารถเพิ่มเหตุผลnodiscard
ตาม[[nodiscard("reason")]]
ที่ระบุไว้ใน: https://en.cppreference.com/w/cpp/language/attributes/nodiscard
GCC warn_unused_result
แอตทริบิวต์
ก่อนการกำหนดมาตรฐาน[[nodiscard]]
และสำหรับ C ก่อนที่พวกเขาจะตัดสินใจกำหนดมาตรฐานแอตทริบิวต์ในที่สุด GCC ได้ใช้ฟังก์ชันเดียวกันกับwarn_unused_result
:
int f() __attribute__ ((warn_unused_result));
int f() {
return 1;
}
int main() {
f();
}
ซึ่งจะช่วยให้:
main.cpp: In function ‘int main()’:
main.cpp:8:6: warning: ignoring return value of ‘int f()’, declared with attribute warn_unused_result [-Wunused-result]
8 | f();
| ~^~
ควรสังเกตว่าเนื่องจาก ANSI C ไม่มีมาตรฐานสำหรับสิ่งนี้ ANSI C จึงไม่ได้ระบุว่าฟังก์ชันไลบรารีมาตรฐาน C ใดมีแอตทริบิวต์หรือไม่ดังนั้นการใช้งานจึงได้ทำการตัดสินใจด้วยตนเองว่าควรทำเครื่องหมายอะไรหรือไม่warn_unuesd_result
ซึ่ง เป็นเหตุผลว่าทำไมโดยทั่วไปแล้วคุณจะต้องใช้การแค(void)
สต์เพื่อละเว้นผลตอบแทนของการเรียกใช้ฟังก์ชันไลบรารีมาตรฐานเพื่อหลีกเลี่ยงคำเตือนในการใช้งานใด ๆ
ทดสอบใน GCC 9.2.1, Ubuntu 19.10