2013-01-15 11 views
22

W moim kodu C++ 11 otrzymuję szczęk ostrzeżenie „deklaracja wymaga destruktora exit-time” w następującym przypadku:Jak radzić sobie z ostrzeżeniem "exit-time destructor" w klangu?

static const std::map<int, const someStruct> mymap = { 
    {1, { 
     "A", 
     "B", 
     "C" 
    }}, 
    {2, { 
     "D", 
     "E", 
     "F" 
    }} 
}; 

O ile mi zrozumieć do Google „exit czasie destruktor” jest wymagane niszczyć main() i statykę w deterministyczny sposób, aby zapobiec awariom przy wyjściu z powodu "już zwolnionych zmiennych". Czy to prawda? Czy ktoś może to lepiej wyjaśnić?

Plus: Co mogę z tym zrobić (nie chcę wyłączyć ostrzeżenia)? Powyższy kod jest używany tylko w kontekście jednego wątku.

Wygląda na to, że Chromium radzi sobie z takimi przypadkami; Czy to też byłaby właściwa droga dla mojej sprawy?

#define CR_DEFINE_STATIC_LOCAL(type, name, arguments) \ 
    static type& name = *new type arguments 

(Źródło: https://chromium.googlesource.com/chromium/src/+/32352ad08ee673a4d43e8593ce988b224f6482d3/base/basictypes.h)

Odpowiedz

14

Globalne i funkcyjne obiekty statyczne dostanie ich destruktory wywoływana gdy aplikacja jest wyjściem. te destruktory są "destruktorami czasu wyjścia". i są wywoływane w odwrotnej kolejności, w jakiej zostały zbudowane.

Jak już powiedziałeś, jeśli niektóre z tych destruktorów dotkną już zniszczonych obiektów, Twój program może ulec awarii. Ponadto, destruktory działające w czasie wyjścia spowodują, że program będzie wolniejszy, a większość czasu nie będzie konieczne dla poprawności programu (ponieważ kiedy program zostanie zakończony, i tak zwolni całą swoją pamięć).

Ostrzeżenie oznacza po prostu, że masz destruktory, które będą uruchamiane w czasie wyjścia.

Zaproponowana przez ciebie poprawka spowoduje przydzielenie obiektu, który nie spowoduje automatycznego zniszczenia przy wyjściu programu. W twoim przypadku jest to prawdopodobnie wystarczająco dobre.

+0

W zależności od tego, co robi destruktor 'someStruct'. Zazwyczaj nie podchodzę do uruchamiania destruktorów. Zarządzanie pamięcią może już nie być problemem przy wyjściu z programu, ale inne nietrywialne operacje będą musiały zostać uruchomione. W bardziej złożonym scenariuszu szybko staje się trudne do udowodnienia, że ​​nie działające destruktory nie mają żadnego efektu odwrotnego. Co więcej, spowolnienie przy wyjściu z programu jest zauważalne tylko wtedy, gdy zostaną wydane duże porcje pamięci. –

+0

Tak, dlatego mówię "prawdopodobnie" i "przez większość czasu". Jeśli destruktory współdziałają z resztą systemu za pośrednictwem IO, to chcesz, aby te destruktory działały. Prostym przykładem może być globalny obiekt konfiguracyjny, który zapisuje ustawienia na dysku, gdy program kończy pracę, a ty opierasz się na destruktorze, aby wiedzieć, kiedy to się stanie (nie, że jestem zwolennikiem kodu, który to robi). – yiding

+1

@KonradRudolph Struktura jest trzy "const char *". Dlatego mój współpracownik słusznie twierdzi, że alokacja sterty jest przesadzona. Czy istnieje sposób na uwolnienie tego ostrzeżenia bez alokacji sterty? –

Powiązane problemy