Сейчас я нахожусь в процессе очистки кода моего решения, которое состоит из статической библиотеки и двух приложений, которые зависят от нее.Как часть этой очистки кода, я конвертировал все свои циклы через std :: vectors, чтобы использовать итераторы, а не индексы.Все шло хорошо, пока я не преобразовал функцию (в библиотеке), которая вызывается при создании глобального объекта (в приложении).Рассматриваемая функция заполняет std :: vector, а затем ищет вектор для объекта, который соответствует описанию, переданному функции, возвращая первое совпадение.Если совпадений не найдено, передняя часть вектора возвращается.
Мне удалось уменьшить проблему до следующего кода:
Библиотека - Bar.h
struct Bar
{
int val;
Bar(int val = 0);
static Bar const& ByVal(int val);
};
Библиотека - Bar.cpp
#include "Bar.h"
#include <vector>
using namespace std;
namespace { vector<Bar> bars; } // It is irrelevant whether bars is in an
// anonymous namespace or not; the results are
// the same.
Bar::Bar(int _val) : val(_val) { }
Bar const& Bar::ByVal(int val)
{
if (bars.empty())
{
bars.push_back(Bar(1));
bars.push_back(Bar(2));
}
#if 1
for (vector<Bar>::const_iterator it = bars.begin();
it != bars.end();
++it) // The assertion fails here. However, when the for loop is
// replaced with a while loop, it's the it != bars.end() part
// that fails.
{
if (it->val == val)
return *it;
}
return bars.front();
#else
for (size_t i = 0;
i < bars.size();
++i)
{
if (bars[i].val == val)
return bars[i];
}
return bars[0];
#endif
}
Приложение - Foo.cpp
#include <Bar.h>
#include <iostream>
using namespace std;
struct Foo
{
Foo()
{
Bar bar = Bar::ByVal(0);
cout << bar.val << endl;
}
};
Foo foo;
int main(int argc, char** argv)
{
return 0;
}
Если условное выражение препроцессора в Bar.cpp изменено на 0, код выполняется безупречно.В противном случае отображается следующее утверждение:
Debug Assertion Failed!
Program: C:\Work\Reduction\Debug\Foo.exe
File: c:\program files (x86)\microsoft visual studio 10.0\vc\include\vector
Line: 238
Expression: vector iterators not compatible
Это новое решение с новыми проектами в Visual Studio 2010. Единственные параметры, которые были изменены в проектах, были те, которые были необходимы для получения приложения.связать со статической библиотекой.
Пытаясь выяснить, что является причиной сбоя, я обнаружил, что код работает при следующих условиях:
- При компиляции в Releasemode.
- Когда вектор баров библиотеки объявляется как extern и определяется в самом приложении.
- Когда переменная foo приложения перемещается внутри функции main ().
- Когда код из библиотеки целиком переносится в приложение.
- При компиляции в Visual Studio 2008.
Любая помощь будет принята с благодарностью, даже если это будет означатьвернуться к использованию индексов или VS2008.Я отчаянно искал и бился головой по этому вопросу уже почти два дня.