void UserThread::ProcessCommand_ListGroups ()
{
if (!session->get_right_admin())
throw command_exception (msg_no_rights);
char grpname[100];
xbShort retcode;
struct GroupInfo
{
string name;
BYTE r_admin;
BYTE r_load;
BYTE r_config;
};
list<GroupInfo> groups;
DWORD grp_count = 0;
{
DataMultiLock lock (false, false, true);
{
xbNdx &idx = lock.get_groups_index_name();
xbDbf &dbf = lock.get_groups_table();
retcode = idx.GetFirstKey();
while (retcode == XB_NO_ERROR)
{
if (dbf.GetField(groups_field_chd)[0] == 'Y')
{
retcode = idx.GetNextKey();
continue;
};
++grp_count;
dbf.GetField (groups_field_name, grpname);
XBaseWork::del_ws(grpname);
groups.push_back (GroupInfo());
groups.back().name = grpname;
groups.back().r_admin = ((dbf.GetField(groups_field_r_admin)[0] == 'Y') ? 1 : 0);
groups.back().r_load = ((dbf.GetField(groups_field_r_load)[0] == 'Y') ? 1 : 0);
groups.back().r_config = ((dbf.GetField(groups_field_r_config)[0] == 'Y') ? 1 : 0);
retcode = idx.GetNextKey();
};
if (retcode != XB_EOF)
throw exception (xbase.GetErrorMessage(retcode));
}
}
sock << ans_accepted << grp_count;
list<GroupInfo>::const_iterator iter = groups.begin();
list<GroupInfo>::const_iterator end_iter = groups.end();
for (; iter != end_iter; ++iter)
sock << (iter->name) << (iter->r_admin) << (iter->r_load) << (iter->r_config);
};
Локальный тип - параметр шаблона
Код:
при компиляции которого в студии 2005-й выдается ошибка C1001 (внутренняя ошибка компилятора).
Потратил пол-дня, пытаясь как-то выйти из ситуации, в результате скачал Dev-cpp 4.9.9.2 и попробовал скомпилить в нем, он ругнулся на применение локального типа (struct GroupInfo) в строке
list<GroupInfo> groups;
после чего я вернулся в студию и попробовал структуру GroupInfo
вынести за пределы метода ProcessCommand_ListGroups, и код стал компилиться...
В связи с этим вопрос. Получается, локальные типы нельзя использовать как параметры шаблона???
Предположим, что так... Но ошибка начала вылезать только после реорганизации кода (я перенес некоторые функции в другие файлы, изменил названия некоторых типов, в том числе DataMultiLock раньше назывался по-другому), а до этой реорганизации все компилировалось!
Конкретный текст ошибки:
c:\program files\microsoft visual studio 8\vc\include\xmemory(145) : fatal error C1001: An internal error has occurred in the compiler.
(compiler file 'msc1.cpp', line 1392)
Строка 145 в xmemory:
Код:
pointer allocate(size_type _Count)
/*Это строка 145*/ { // allocate array of _Count elements
return (_Allocate(_Count, (pointer)0));
}
/*Это строка 145*/ { // allocate array of _Count elements
return (_Allocate(_Count, (pointer)0));
}
Решил разобраться, т.к. подобное тоже когда-то случалось.
Накатил сейчас SP1 - компилиться перестал даже простейший проект :)
Нашел в инете, что для исправления бага достаточно перетащить из папки src в include файл xutility. Так и сделал - все заработало, локальные типы можно юзать. Так что, думаю, что это глюк.
Цитата: cheburator
В связи с этим вопрос. Получается, локальные типы нельзя использовать как параметры шаблона???
14.3.1 Template type arguments
....
2. A local type, a type with no linkage, an unnamed type or a type compounded from any of these types shall not be used as a template-argument for a template type-parameter. [Example:
Код:
template <class T> class X { /* ... */ };
void f()
{
struct S { /* ... */ };
X<S> x3; // error: local type used as template-argument
X<S*> x4; // error: pointer to local type used as template-argument
}
void f()
{
struct S { /* ... */ };
X<S> x3; // error: local type used as template-argument
X<S*> x4; // error: pointer to local type used as template-argument
}
—end example] [Note: a template type argument may be an incomplete type (3.9). ]
Собсно, в любом случае - глюк в компиляторе MSVC. Да еще плюс несоответствие стандарту.
мдэ, думал 2005-я полностью отвечает стандарту...а получается что такое можно скомпилить, накатив СП1.
Код:
throw std::exception ("Ашыпка");
msvc компилит, а Dev-cpp нет, говорит, что нет такого конструктора - exception (const char* const&), который есть в студии. И, соответственно, метод what() не реализован, а в студии реализован.
Вышел из положения так.
Код:
class my_exception : public std::exception
{
public:
my_exception (const char * const &e)
:exception(), m_what(e)
{
};
const char *what() const throw()
{
return m_what;
};
private:
const char * const &m_what;
};
{
public:
my_exception (const char * const &e)
:exception(), m_what(e)
{
};
const char *what() const throw()
{
return m_what;
};
private:
const char * const &m_what;
};
И еще момент.
Код:
class A
{
public:
void B();
}
/*...*/
void A::B() throw()
// Здесь ругается
{
}
{
public:
void B();
}
/*...*/
void A::B() throw()
// Здесь ругается
{
}
Dev-cpp ругнулся на то, что спецификации исключений не совпадают в объявлении и реализации, а студия закрывает на это глаза...
Ну, и вдогонку, еще момент...
Код:
// Файл a.h (непосредственно в каталоге проекта)
#include "x/b.h"
// Файл b.h (в каталоге x)
#include "x/c.h" // катит в студии, не катит в Dev-cpp
#include "c.h" // наоборот, катит в Dev-cpp, не катит в студии
// Файл c.h находится в каталоге x
#include "x/b.h"
// Файл b.h (в каталоге x)
#include "x/c.h" // катит в студии, не катит в Dev-cpp
#include "c.h" // наоборот, катит в Dev-cpp, не катит в студии
// Файл c.h находится в каталоге x
В общем, студия всегда измеряет пути от проекта, а Dev-cpp - от того каталога, где находится текущий файл.
Вот такая вот кроссплатформенность :)