C ++ 17 [[nodiscard]]
C ++ 17 đã chuẩn hóa "giá trị trả về doanh nghiệp bị bỏ qua" với một thuộc tính.
Do đó, tôi hy vọng rằng các triển khai tuân thủ sẽ luôn chỉ cảnh báo khi nodiscard
được đưa ra và không bao giờ cảnh báo khác.
Thí dụ:
main.cpp
[[nodiscard]] int f() {
return 1;
}
int main() {
f();
}
biên dịch:
g++ -std=c++17 -ggdb3 -O0 -Wall -Wextra -pedantic -o main.out main.cpp
kết quả:
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() {
|
Tất cả những điều sau đây đều tránh được cảnh báo:
(void)f();
[[maybe_unused]] int i = f();
Tôi không thể sử dụng maybe_unused
trực tiếp trong f()
cuộc gọi:
[[maybe_unused]] f();
cho:
main.cpp: In function ‘int main()’:
main.cpp:6:5: warning: attributes at the beginning of statement are ignored [-Wattributes]
6 | [[maybe_unused]] f();
| ^~~~~~~~~~~~~~~~
Việc ép kiểu(void)
dường như không bắt buộc nhưng được "khuyến khích" trong tiêu chuẩn: Làm cách nào để tôi có thể cố ý loại bỏ giá trị trả về [[thẻ nút]]?
Cũng như đã thấy từ thông báo cảnh báo, một "giải pháp" cho cảnh báo là thêm -Wno-unused-result
:
g++ -std=c++17 -ggdb3 -O0 -Wall -Wextra -pedantic -Wno-unused-result -o main.out main.cpp
mặc dù tất nhiên tôi sẽ không khuyên bạn nên bỏ qua các cảnh báo trên toàn cầu như thế này.
C ++ 20 cũng cho phép bạn thêm một lý do để các nodiscard
như trong [[nodiscard("reason")]]
như đã đề cập tại địa chỉ: https://en.cppreference.com/w/cpp/language/attributes/nodiscard
warn_unused_result
Thuộc tính GCC
Trước khi tiêu chuẩn hóa [[nodiscard]]
và đối với C trước khi cuối cùng họ quyết định tiêu chuẩn hóa các thuộc tính, GCC đã triển khai cùng chức năng chính xác với warn_unused_result
:
int f() __attribute__ ((warn_unused_result));
int f() {
return 1;
}
int main() {
f();
}
mang lại:
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();
| ~^~
Cần lưu ý rằng vì ANSI C không có tiêu chuẩn cho điều này, ANSI C không chỉ định các hàm thư viện tiêu chuẩn C có thuộc tính nào hay không và do đó việc triển khai đã tự đưa ra quyết định về cái gì nên hay không được đánh dấu warn_unuesd_result
, cái nào là lý do tại sao nói chung bạn sẽ phải sử dụng (void)
ép kiểu để bỏ qua trả về của bất kỳ lệnh gọi nào đến các hàm thư viện tiêu chuẩn để tránh hoàn toàn các cảnh báo trong bất kỳ triển khai nào.
Đã thử nghiệm trong GCC 9.2.1, Ubuntu 19.10.