Ich habe einige Code, wo eine statische Methode aufgerufen wird, und die statische std::unordered_map
innerhalb der gleichen Datei ist nicht initialisiert. Ich verstehe die statische Initialisierung zwischen zwei Kompiliereinheiten ist "undefined" und es gibt viele SO
Fragen zum Thema; Wenn ich jedoch std::vector
verwende, tritt das Problem nicht auf. Auch der Code kann ausführen, aber ich bin verwirrt, warum diese spezifischen kompilieren Bestellungen nicht funktionieren. SO
, meine Fragen sind:C++ statische unorderd_map in statischen Methode verwendet wird nicht initialisiert
- Es gibt eine andere ist
SO
Frage (die ich nicht in der Lage gewesen bin zu finden!) Über statische Initialisierung und dynamische Initialisierung von statischen Variablen. Ist dieser Fehler aufgrundstd::undored_map
tatsächlich eine dynamische Initialisierung? - gibt es eine Möglichkeit, diesen Code zu erhalten, um die
std::unordered_map
wie ich erwartet zu initialisieren? Ich versuche tatsächlich, eine statische Bibliothek.lib
oder.a
zu erstellen. Wenn ich die statische Bibliothek verknüpfe, muss sie in der Regel zuletzt ausgeführt werden, und der Fehler tritt auf. - gibt es irgendwelche Problemumgehungen dafür? Eine Option, an die ich gedacht habe, ist die Erstellung eines
std::vector
und einesstd::unordered_map
. Verwenden Sie diestd::vector
, während diestd::unordered_map
nicht initialisiert ist (überbool _map_is_initialized
). Ändern Sie die Initialisierung desstd::unordered_map
, um explizit dynamisch zu sein, indem Sie eine Funktion aufrufen, die über die Werte instd::vector
iteriert, umstd::unordered_map
zu erzeugen.
Linux
g++ -std=c++1y -g -c thing.cpp
g++ -std=c++1y -g -c main.cpp
g++ -g main.o thing.o -o main
./main
Dies führt zu einem Floating point exception (core dumped)
Fehler. Durch gdb
konnte ich herausfinden, dass hashtable_policy.h
trys __num % __den;
wo __den==0
ist. Unter Verwendung von gdb
scheint es, als ob Thing::Things
nicht initialisiert ist.
(gdb) break thing.cpp:12
(gdb) run
(gdb) print Thing::Things
No symbol "Things" in specified context.
(gdb) print thing
$1 = (Thing *) 0x618c20
Windows-
cl /EHsc /Zi /c main.cpp
cl /EHsc /Zi /c thing.cpp
link /debug main.obj thing.obj
main
In meinem eigentlichen Code, führte dies zu einer sehr klaren Segmentierung Fehler; In diesem Beispiel wird jedoch nur ein Popup geöffnet, das besagt, dass die Anwendung fehlgeschlagen ist. ... Ich habe keine bessere Diagnostik gemacht.
-Code
thing.cpp
#include<iostream> #include "thing.hpp" std::vector<Thing*> Before; // EDIT: added std::unordered_map<std::string, Thing*> Thing::Things; std::vector<Thing*> After; // EDIT: added Thing::Thing(std::string name) : name(name) { } bool Thing::Register(Thing *thing) { std::cout << "no worries, vectors initialized..." << std::endl; Thing::Before.push_back(thing); // EDIT: added Thing::After.push_back(thing); // EDIT: added std::cout << "added to vectors, about to fail..." << std::endl; Thing::Things[thing->name] = thing; return true; }
thing.hpp
#pragma once #include <string> #include <unordered_map> class Thing { public: static std::vector<Thing*> Before; // EDIT: added static std::unordered_map<std::string, Thing*> Things; static std::vector<Thing*> After; // EDIT: added static bool Register(Thing* thing); std::string name; Thing(std::string name); }; #define ADD_THING(thing_name) \ static bool thing_name## _is_defined = Thing::Register(new Thing(#thing_name));
main.cpp
EDIT
Wenn der Auftrag innerhalb einer bestimmten Kompilierung Einheit gewährleistet ist, zu tun, warum static std::vector<Thing*> Thing::Before
und static std::vector<Thing*> Thing::After
erhält initialisiert, aber static std::unordered_map<std::string, Thing*> Thing::Things
nicht?
siehe hier: https://isocpp.org/wiki/faq/ctors#static-init-order – Nim
Related: http://stackoverflow.com/q/211237/335858 – dasblinkenlight
Können Sie die ADD_THING-Makros nach innen verschieben Main()? Oder eine andere Funktion, die von main() aufgerufen wird? – nephtes