Mam aplikację wieloplatformową i w niektórych moich funkcjach nie wszystkie wartości przekazywane do funkcji są wykorzystywane. Dlatego dostaję ostrzeżenie od GCC z informacją, że istnieją nieużywane zmienne.
Jaki byłby najlepszy sposób kodowania wokół ostrzeżenia?
#Ifdef wokół funkcji?
#ifdef _MSC_VER
void ProcessOps::sendToExternalApp(QString sAppName, QString sImagePath, qreal qrLeft, qreal qrTop, qreal qrWidth, qreal qrHeight)
#else
void ProcessOps::sendToExternalApp(QString sAppName, QString sImagePath, qreal /*qrLeft*/, qreal /*qrTop*/, qreal /*qrWidth*/, qreal /*qrHeight*/)
#endif
{
Jest to tak brzydkie, ale wydaje się, że preferuje to kompilator.
Czy też przypisuję zero do zmiennej na końcu funkcji? (którego nienawidzę, ponieważ zmienia coś w przepływie programu, aby wyciszyć ostrzeżenie kompilatora).
Czy jest właściwy sposób?
c++
gcc
warnings
gcc-warning
Phil Hannent
źródło
źródło
Q_UNUSED
właśnie makro. Sprawdź to w dokumentacji.Odpowiedzi:
Możesz umieścić go w
(void)var;
wyrażeniu „ ” (nic nie robi), aby kompilator zobaczył, że jest używany. Jest to przenośne między kompilatorami.Na przykład
Lub,
źródło
Q_UNUSED
w zasadzie realizowane.#define UNUSED(expr) (void)(expr)
powinno działać też (bez do-while).template<typename... Args> void f(const Args&... args)
Nie mogę pisać(void)args;
lub(void)args...;
ponieważ oba są błędami składniowymi.W GCC i Clang możesz użyć
__attribute__((unused))
dyrektywy preprocesora, aby osiągnąć swój cel.Na przykład:
źródło
C ++ 17 udostępnia teraz ten
[[maybe_unused]]
atrybut.http://en.cppreference.com/w/cpp/language/attributes
Całkiem miły i standardowy.
źródło
Twoje obecne rozwiązanie jest najlepsze - skomentuj nazwę parametru, jeśli go nie używasz. Dotyczy to wszystkich kompilatorów, więc nie musisz używać procesora wstępnego, aby zrobić to specjalnie dla GCC.
źródło
g++
ostrzega o tym). W takim przypadku, co byś polecił?Aktualizacja C ++ 17
W C ++ 17 otrzymujemy atrybut [[może_nieużywany]], który jest objęty [dcl.attr.unused]
Dla następującego przykładu:
Zarówno clang, jak i gcc generują diagnostykę przy użyciu -Wall -Wextra zarówno dla bar, jak i unused_bool ( Zobacz na żywo ).
Podczas dodawania [[może_nieużywany]] wycisza się diagnostyka:
zobacz to na żywo .
Przed C ++ 17
W C ++ 11 można utworzyć alternatywną formę
UNUSED
makra przy użyciu wyrażenia lambda ( przez Bena Deane'a ) z przechwyceniem nieużywanej zmiennej:Natychmiastowe wywołanie wyrażenia lambda powinno zostać zoptymalizowane, biorąc pod uwagę następujący przykład:
widzimy w godbolt, że połączenie jest zoptymalizowane:
źródło
template <class T> inline void NOTUSED( T const & result ) { static_cast<void>(result); }
Przypuszczam, że w funkcji można również użyć lambda.[&x]{}()
tak naprawdę nie wycisza ostrzeżenia, ale zamiast tego przekazuje ostrzeżenie z funkcji wywołującej do lambda. Minie trochę czasu, zanim kompilatory rozpoznają to jako ostrzeżenie, ale clang-tidy już narzeka na nieużywaną zmienną na liście przechwytywania.Jeszcze czystszym sposobem jest po prostu komentowanie nazw zmiennych:
źródło
#if 0 / #endif
komentarzy blokowych.Współpracownik właśnie wskazał mi to miłe małe makro tutaj
Dla ułatwienia dołączę poniższe makro.
źródło
gccdomyślnie nie oznacza tych ostrzeżeń. To ostrzeżenie musiało zostać włączone jawnie przez przekazanie
-Wunused-parameter
do kompilatora lub pośrednio przez przekazanie-Wall -Wextra
(lub ewentualnie inną kombinację flag).Nieużywane ostrzeżenia dotyczące parametrów można po prostu ukryć, przekazując
-Wno-unused-parameter
do kompilatora, ale należy pamiętać, że ta flaga wyłączająca musi pojawić się po ewentualnych flagach włączających dla tego ostrzeżenia w wierszu polecenia kompilatora, aby mogła zadziałać.źródło
bez makr i przenośny sposób na zadeklarowanie jednego lub więcej parametrów jako nieużywanych:
źródło
Korzystanie z dyrektyw preprocesora jest przez większość czasu uważane za zło. Idealnie chcesz ich uniknąć, jak szkodników. Pamiętaj, że zrozumienie kodu przez kompilator jest łatwe, a innym programistom zrozumienie kodu jest znacznie trudniejsze. Kilkadziesiąt takich przypadków tutaj i tam bardzo utrudnia czytanie sobie później lub innym.
Jednym ze sposobów może być zestawienie parametrów w jakąś klasę argumentów. Następnie możesz użyć tylko podzbioru zmiennych (tak jak w rzeczywistości przypisujesz 0) lub posiadasz różne specjalizacje tej klasy argumentów dla każdej platformy. Może to jednak nie być tego warte, musisz przeanalizować, czy będzie pasować.
Jeśli umiesz czytać niemożliwe szablony, możesz znaleźć zaawansowane porady w książce „Wyjątkowe C ++”. Gdyby ludzie, którzy czytali Twój kod, mogliby zdobyć swój zestaw umiejętności obejmujący szalone rzeczy nauczane w tej książce, miałbyś piękny kod, który można łatwo odczytać. Kompilator byłby również świadomy tego, co robisz (zamiast ukrywać wszystko przez wstępne przetwarzanie)
źródło
#define UNUSED(expr) (void)(expr)
odpowiednim.Po pierwsze ostrzeżenie jest generowane przez definicję zmiennej w pliku źródłowym, a nie w pliku nagłówkowym. Nagłówek może pozostać nieskazitelny i powinien, ponieważ do generowania dokumentacji API możesz używać czegoś takiego jak doxygen.
Zakładam, że masz zupełnie inną implementację w plikach źródłowych. W takich przypadkach możesz albo skomentować obrażający parametr, albo po prostu napisać parametr.
Przykład:
Może to wydawać się tajemnicze, więc zdefiniowane makro takie jak UNUSED. Sposób, w jaki MFC to zrobił:
W ten sposób ostrzeżenie nadal pojawia się w kompilacjach debugowania, może być pomocne.
źródło
Czy zawsze nie jest bezpiecznie komentować nazwy parametrów? Jeśli nie, możesz zrobić coś takiego
To trochę mniej brzydkie.
źródło
Widziałem to zamiast
(void)param2
wyciszenia ostrzeżenia:Wygląda na to, że zostało to dodane w C ++ 11
źródło
Korzystanie z
UNREFERENCED_PARAMETER(p)
może działać. Wiem, że jest zdefiniowany w WinNT.h dla systemów Windows i może być łatwo zdefiniowany również dla gcc (jeśli jeszcze go nie ma).UNREFERENCED PARAMETER(p)
jest zdefiniowany jakow WinNT.h.
źródło
Użyj flagi kompilatora, np. Flagi dla GCC:
-Wno-unused-variable
źródło
Możesz użyć,
__unused
aby powiedzieć kompilatorowi, że zmienna może nie być używana.źródło
__unused
nie jest to standardowy C ++, a co więcej, nie jest to, co opublikowałeś ... To jest Objective-C. Tak więc ta odpowiedź jest naprawdę przydatna tylko dla określonych kompilatorów i sprawia, że kod jest nieprzenośny i faktycznie nie jest poprawny, ponieważ kod użytkownika nie powinien używać identyfikatorów zaczynających się od__
, które są zarezerwowane dla implementacji.W C ++ 11 używam tego rozwiązania:
Zweryfikowano, że jest przenośny (przynajmniej w nowoczesnych msvc, clang i gcc) i nie generuje dodatkowego kodu, gdy włączone są optymalizacje. Bez optymalizacji wykonywane jest dodatkowe wywołanie funkcji, a odniesienia do parametrów są kopiowane na stos, ale nie są w to zaangażowane makra.
Jeśli problem stanowi dodatkowy kod, możesz zamiast tego użyć tej deklaracji:
ale w tym momencie makro zapewnia lepszą czytelność:
źródło
Działa to dobrze, ale wymaga C ++ 11
źródło
ALLCAPS
do czegokolwiek poza makrami, co sprawia, że wyglądają brzydko i niepożądane, ale tak naprawdę nie ma w tym nic złego, z wyjątkiem tego, żestatic_cast
byłoby ładniej.Odkryłem, że większość przedstawionych odpowiedzi działa tylko dla lokalnej nieużywanej zmiennej i spowoduje błąd kompilacji dla nieużywanej statycznej zmiennej globalnej.
Kolejne makro potrzebne do ukrycia ostrzeżenia o nieużywanej statycznej zmiennej globalnej.
Działa to, ponieważ nie będzie generowane ostrzeżenie dla niestatycznej zmiennej globalnej w anonimowej przestrzeni nazw.
Wymagany jest jednak C ++ 11
źródło
Lol! Nie sądzę, żeby było inne pytanie na temat SO, które ujawniło wszystkich heretyków skorumpowanych przez Chaos lepiej niż to!
Z całym szacunkiem dla C ++ 17 istnieje wyraźna wytyczna w Podstawowych Wytycznych C ++ . AFAIR, jeszcze w 2009 roku ta opcja była dostępna tak samo jak dzisiaj. A jeśli ktoś powie, że w Doxygen jest uważany za błąd, oznacza to, że w Doxygen jest błąd
źródło
Nie widzę twojego problemu z ostrzeżeniem. Udokumentuj to w nagłówku metody / funkcji, że kompilator xy wyda tutaj (poprawne) ostrzeżenie, ale te zmienne są potrzebne dla platformy z.
Ostrzeżenie jest prawidłowe, nie trzeba go wyłączać. Nie unieważnia to programu - należy go jednak udokumentować, że istnieje powód.
źródło