Почему это нарушение доступа происходит с флагами / Og и / GL, с передачей по ссылке? - PullRequest
9 голосов
/ 30 августа 2011

Когда (и только когда) я компилирую свою программу с флагом /Og и /GL с использованием компилятора DDK C ++ Windows Server 2003 (это отлично *) 1008 * в WDK 7.1, а также в Visual Studio 2010!), Я получаю нарушение прав доступа при запуске этого:

#include <algorithm>
#include <vector>

template<typename T> bool less(T a, T b) { return a < b; }

int main()
{
    std::vector<int> s;

    for (int i = 0; i < 13; i++)
        s.push_back(i);

    std::stable_sort(s.begin(), s.end(), &less<const int&>);
}

Нарушение прав доступа исчезает , когда я изменяю последнюю строку на

    std::stable_sort(s.begin(), s.end(), &less<int>);

- другими словами, он исчезает, когда я позволяю моему элементу скопировать 1018 * вместо простого , на который ссылается .

(у меня вообще нет многопоточности.)

Почему что-то подобное произошло? Я вызываю какое-то неопределенное поведение, проходя мимо const &?


  • Флаги компилятора:

    /Og /GL /MD /EHsc
    
  • Флажки компоновщика: (нет)

  • ВКЛЮЧИТЬ переменную среды:

    C:\WinDDK\3790.1830\inc\crt
    
  • Переменная среды LIB:

    C:\WinDDK\3790.1830\lib\crt\I386;C:\WinDDK\3790.1830\lib\wxp\I386
    
  • Операционная система: Windows 7 x64

  • Платформа: 32-битная компиляция выдает ошибку (64-битная работает правильно)


Edit:

Я только что попробовал это с Windows XP DDK (это C:\WinDDK\2600), и я получил:

error LNK2001: unresolved external symbol
    "bool __cdecl less(int const &,int const &)" (?less@@YA_NABH0@Z)

но , когда я изменил его из шаблона на обычную функцию , он волшебным образом работал с обоими компиляторами!

Я подозреваю, что это означает, что я обнаружил ошибку, которая возникает при получении адреса шаблонной функции с использованием компиляторов DDK. Любые идеи, если это может быть случай, или если это другой угловой случай, о котором я не знаю?

Ответы [ 2 ]

5 голосов
/ 30 августа 2011

Я пробовал это с установкой 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, найденных с разными атрибутами».Кажется, я помню это предупреждение, которое было безопасно игнорировать, но я действительно не помню.Хотя я не думаю, что что-то из этого имеет какое-либо отношение к ошибке.

0 голосов
/ 30 августа 2011

Если вы не получите его на более новых компиляторах, это, скорее всего, ошибка.

У вас есть небольшое автономное воспроизведение?

...