Я пробовал это с установкой Windows Server 2003 DDK SP1 (DDK без SP1 в данный момент недоступен).Это использует cl.exe версии 13.10.4035 для 80x86.Похоже, у вас та же проблема, которую вы обнаружили.
Если вы пошагово просматриваете код в отладчике (что немного упрощается, если следовать файлу .cod, созданному с использованием параметра /FAsc
)вы обнаружите, что функция less<int const &>()
ожидает вызова с указателями на значения int
, переданные в eax
и edx
.Однако функция, которая вызывает less<int const&>()
(с именем _Insertion_sort_1<>()
), вызывает ее, передавая указатели в стеке.
Если вы превращаете шаблонную функцию less
в не шаблонную функцию, она ожидает параметрычтобы быть переданным в стек, так что все счастливы.
Немного больше интереса, что происходит, когда вместо less<const int&>
вместо less<int>
.Нет сбоев, но ничего не сортируется (конечно, вам нужно изменить программу, чтобы начать с несортированного вектора, чтобы увидеть этот эффект).Это связано с тем, что при изменении на less<int>
функция less
больше не разыменовывает какие-либо указатели - она ожидает, что фактические значения int будут переданы в регистрах (ecx
и edx
в этом случае).Но разыменование указателя не означает сбой.Однако вызывающая сторона, _Insertion_sort_1
, все еще передает аргументы в стеке, поэтому сравнение, выполняемое less<int>
, не имеет ничего общего со значениями в векторе.
Так вот, что происходит, но яна самом деле не знаю, в чем причина - как уже упоминали другие, похоже, что ошибка компилятора связана с оптимизацией.
Поскольку ошибка, по-видимому, была исправлена, сообщать о ней явно нет смысла (компилятор в этой версии DDK соответствует чему-то близкому к VS 2003 / VC 7.1).
Кстати - я не смог заставить ваш пример полностью скомпилироваться - чтобы его вообще собрать, япришлось включить bufferoverflowu.lib
, чтобы заставить стек проверять ссылки, и даже тогда компоновщик жаловался на «несколько разделов .rdata, найденных с разными атрибутами».Кажется, я помню это предупреждение, которое было безопасно игнорировать, но я действительно не помню.Хотя я не думаю, что что-то из этого имеет какое-либо отношение к ошибке.