Wenn (und nur wenn) kompiliere ich mein Programm mit dem /Og
und /GL
flag mit dem Windows Server 2003 DDK C ++ - Compiler (es ist ) Fein auf WDK 7.1 sowie Visual Studio 2010!), bekomme ich eine Zugriffsverletzung, wenn ich dies ausführen:
Die Zugriffsverletzung verschwindet , wenn ich die letzte Zeile in
ändere %Vor%- mit anderen Worten, es geht weg, wenn ich meinen Gegenstand kopiert statt nur verwiesen bekommen lasse.
(Ich habe keinerlei Art von Multithreading.)
Warum würde so etwas passieren? Bringe ich ein undefiniertes Verhalten durch die Weitergabe von const &
?
Compiler-Flags:
%Vor%Linker-Flags: (keine)
INCLUDE-Umgebungsvariable:
%Vor%LIB-Umgebungsvariable:
%Vor%Betriebssystem: Windows 7 x64
Plattform: 32-Bit-Kompilierung gibt Fehler (64-Bit-Läufe korrekt)
Ich habe es gerade mit dem Windows XP DDK versucht (das ist C:\WinDDK00
) und ich habe:
aber wenn ich es von einer Vorlage zu einer regulären Funktion änderte, funktionierte es wunderbar mit beiden Compilern!
Ich vermute, dass dies bedeutet, dass ich einen Fehler gefunden habe, der passiert, während ich die Adresse einer Template-Funktion mit den DDK-Compilern genommen habe. Irgendwelche Ideen, wenn dies der Fall ist, oder wenn es ein anderer Eckfall ist, von dem ich nichts weiß?
Ich habe dies mit einer Windows Server 2003 DDK SP1-Installation versucht (das Nicht-SP1-DDK ist momentan nicht verfügbar). Dies verwendet CL.exe Version 13.10.4035 für 80 x 86. Es scheint das gleiche Problem zu haben, das Sie gefunden haben.
Wenn Sie den Code in einem Debugger durchgehen (was etwas einfacher ist, wenn Sie der COD-Datei folgen, die mit der Option /FAsc
erzeugt wurde), werden Sie feststellen, dass die less<int const &>()
-Funktion erwartet, dass sie aufgerufen wird die Zeiger auf die int
-Werte, die in eax
und edx
übergeben wurden. Die Funktion, die less<int const&>()
(mit dem Namen _Insertion_sort_1<>()
) aufruft, ruft jedoch die Zeiger auf dem Stapel auf.
Wenn Sie die Template-Funktion less
in eine nicht-Template-Funktion umwandeln, erwartet sie, dass die Parameter auf dem Stack übergeben werden, sodass alle zufrieden sind.
Etwas interessanter ist es, wenn Sie less<const int&>
stattdessen zu less<int>
ändern. Es gibt keinen Absturz, aber es wird auch nichts sortiert (Sie müssten natürlich Ihr Programm ändern, um mit einem nicht sortierten Vektor zu beginnen, um diesen Effekt tatsächlich zu sehen). Das liegt daran, dass beim Ändern von less<int>
die Funktion less
keine Zeiger mehr dereferenziert - sie erwartet, dass die tatsächlichen int-Werte in Registern übergeben werden (in diesem Fall ecx
und edx
). Aber keine Zeigerdereferenz bedeutet keinen Absturz. Der Aufrufer _Insertion_sort_1
übergibt jedoch immer noch die Argumente auf dem Stapel, sodass der Vergleich, der von less<int>
ausgeführt wird, nichts mit den Werten im Vektor zu tun hat.
Das ist also passiert, aber ich weiß nicht wirklich, was die Ursache ist - wie andere bereits erwähnt haben, sieht es wie ein Compilerfehler aus, der sich auf die Optimierungen bezieht.
Da der Fehler anscheinend behoben wurde, hat es offensichtlich keinen Sinn, ihn zu melden (der Compiler in dieser Version des DDK entspricht etwas in der Nähe von VS 2003 / VC 7.1).
Übrigens - ich konnte Ihr Beispiel nicht vollständig sauber kompilieren - um es überhaupt erstellen zu können, musste ich bufferoverflowu.lib
einfügen, um die Stack-Checking-Sachen zu verknüpfen, und selbst dann klagte der Linker über "mehrere '.rdata' Abschnitte mit unterschiedlichen Attributen gefunden". Ich glaube mich daran zu erinnern, dass es eine Warnung war, die ich ignorieren konnte, aber ich kann mich nicht erinnern. Ich denke aber, dass keiner von beiden etwas mit dem Fehler zu tun hat.
Tags und Links c++ stl visual-c++ access-violation undefined-behavior