Здорово лопухнулся я с компилятором
Я-то думал, что заменил стандартный, а оказывается, и нет. Я оказался введен в заблуждение тем, что при ошибках выдавалось не стандартное "cl.exe", а какой-то другой экзешник. Поэтому, неудивительно, что никаких ошибок компиляции не вылезало.
Чтобы включить использование интеловского компилятора, надо выбрать в меню "Tools" "Intel C++ Compiler Selection Tool" и там установить, что должен использоваться интеловский компилятор. Установил. Вот тут-то оно все и вылезло
Рассказываю по порядку. Вылезло три основных типа ошибок и предупреждений:
1) Ругается на такие строки:
CSelHistDlg(class PSelHistItemArray *,class CWnd *); //37
следующим образом:
error: invalid redeclaration of type name "PSelHistItemArray"
Решается элементарным образом - убираем слово class перед PSelHistItemArray. Забавно, но на "class CWnd", "class CValue" не ругается
2) warning #1744: field of class type without a DLL interface used in a class with a DLL interface
ругается на
class IMPORT_1C CGenericItem
{
public:
CPtrArray m_array; // <= на эту строку
CGenericItem(void); //3
virtual ~CGenericItem(void); //17
static CGenericItem * CreateFromString(char const *,int *); //45
};
Вроде бы ему не нравится что в импортируемом из DLL классе используется переменная типа, который не экспортируется из DLL. В принципе, правильно предупреждает. Но в данном случае можно проигнорировать – реализация MFC и у 1С, и у компоненты совпадают. Поэтому в начало файла 1cheaders.h пишем:
#pragma warning (disable : 1744)
3) "Сокрытие имен". "Проблема" отсутствовала в VC6. В новых компиляторах, как я понял, "возникает" регулярно. Суть: в базовом классе есть функция func. В классе-наследнике определяем функцию func, но меняем тип и/или количество параметров. В результате функция базового класса func становится "скрытой". Т.е., чтобы вызвать именно func базового класса, нужно привести объект класса-наследника к базовому классу. Или альтернативный вариант: в определении класса-наследника вставить строку using BaseClass::func; Такие вещи в классах 1С не редкость, поэтому имеем кучу предупреждений. Я ограничился добавлением строки "#pragma warning (disable : 1125)" в 1cheaders.h. Если потом потребуется вызывать функции базовых классов объектов 1С, то либо буду приводить к базовому классу, либо добавлю using.
Ну и еще было кое-что по мелочи. Например, выругался на дублирующееся определение статической переменной в одном классе (в VC6 прокатывало) и т.п. Все решаемо.
Все скомпилировалось, ё-моё!
Все запускается, все тесты проходит нормально. А у меня там наследование одинэсных фреймов и CMyContextBase из 1С++. Так что взаимодействие с 1С не пострадало.
Компилятор оказался сильно дотошным. Находит вещи, которые VC6 не видел. Например, нашел у меня кучу проинициализированных неиспользуемых локальных переменных. VC6 видит только неинициализированные. Т.е. такую неиспользуемую переменную он уже не замечает:
CDbgMemoryBlock *pBlock = NULL;
Это, конечно, хорошо, но в неиспользуемые переменные он также записывает и все IMPLEMENT_MY_CONTEXT.
Нашел мелкий незначительный, но забавный косячок (не в смысле травы
) в CIStringMap, который используется для реализации CMyContextBase. Ругается на строку
ASSERT(m_nCount >= 0); // make sure we don't underflow
Ругательство:
warning #186: pointless comparison of unsigned integer with zero
ASSERT(m_nCount >= 0); // make sure we don't underflow
^
detected during:
instantiation of "void CIStringMap<VALUE, ARG_VALUE>::FreeAssoc(CIStringMap<VALUE, ARG_VALUE>::CAssoc *) [with VALUE=int, ARG_VALUE=int]" at line 518
instantiation of "BOOL={int} CIStringMap<VALUE, ARG_VALUE>::RemoveKey(LPCSTR={const CHAR={char} *}) [with VALUE=int, ARG_VALUE=int]"
А ведь он, зараза такая, прав!!!!
Определение переменной: UINT m_nCount;
А беззнаковую переменную проверять на условие >= 0 - совершенно дохлый номер
Ну и еще есть приколы в сборке релизного варианта. Там все ASSERT'ы зануляются, поэтому выдается много ворнингов на такие, к примеру, вещи в CIStringMapToIndex
bool bFound = (Lookup(szKey, nIndex) == TRUE);
ASSERT( !bFound );
Т.е. bFound становится неиспользуемой переменной
Скорость компиляции заметно замедлилась. Размер релизной DLL увеличился почти в полтора раза. Однако, думаю, останусь на этом компиляторе. Он и стандарт лучше поддерживает (сколько можно на старье сидеть) и вообще дотошный
Ну и, говорят, программы более быстрые генерит