C ++ 17 [[nodiscard]]
C ++ 17 ustandaryzował „zwracaną wartość biznesową ignorowaną” za pomocą atrybutu.
Dlatego mam nadzieję, że zgodne implementacje zawsze będą ostrzegać tylko wtedy, gdy nodiscard
zostaną podane, i nigdy nie będą ostrzegać inaczej.
Przykład:
main.cpp
[[nodiscard]] int f() {
return 1;
}
int main() {
f();
}
skompilować:
g++ -std=c++17 -ggdb3 -O0 -Wall -Wextra -pedantic -o main.out main.cpp
wynik:
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() {
|
Poniższe wszystkie pozwalają uniknąć ostrzeżenia:
(void)f();
[[maybe_unused]] int i = f();
Nie mogłem użyć maybe_unused
bezpośrednio podczas f()
rozmowy:
[[maybe_unused]] f();
daje:
main.cpp: In function ‘int main()’:
main.cpp:6:5: warning: attributes at the beginning of statement are ignored [-Wattributes]
6 | [[maybe_unused]] f();
| ^~~~~~~~~~~~~~~~
Działanie (void)
rzutowania nie wydaje się być obowiązkowe, ale standard jest „ zalecany ”: Jak celowo odrzucić wartość zwracaną przez [[nodiscard]]?
Jak widać z komunikatu ostrzegawczego, jednym „rozwiązaniem” ostrzeżenia jest dodanie -Wno-unused-result
:
g++ -std=c++17 -ggdb3 -O0 -Wall -Wextra -pedantic -Wno-unused-result -o main.out main.cpp
chociaż oczywiście nie polecałbym ignorowania takich ostrzeżeń na całym świecie.
C ++ 20 pozwala również dodać powód do nodiscard
jak w, [[nodiscard("reason")]]
jak wspomniano na: https://en.cppreference.com/w/cpp/language/attributes/nodiscard
warn_unused_result
Atrybut GCC
Przed standaryzacją [[nodiscard]]
i dla C zanim ostatecznie zdecydują się na standaryzację atrybutów, GCC zaimplementowało dokładnie tę samą funkcjonalność z warn_unused_result
:
int f() __attribute__ ((warn_unused_result));
int f() {
return 1;
}
int main() {
f();
}
co daje:
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();
| ~^~
Należy zatem zauważyć, że ponieważ ANSI C nie ma na to standardu, ANSI C nie określa, które funkcje biblioteki standardowej C mają atrybut lub nie, a zatem implementacje podjęły własne decyzje dotyczące tego, co powinno lub nie być oznaczone warn_unuesd_result
, co dlatego generalnie należałoby użyć (void)
rzutowania, aby zignorować zwrot wszelkich wywołań funkcji biblioteki standardowej, aby w pełni uniknąć ostrzeżeń w jakiejkolwiek implementacji.
Przetestowano w GCC 9.2.1, Ubuntu 19.10.