Иллюстрированный самоучитель по Architecture .NET

Типовая безопасность

Программы, написанные на C++, не обладают свойством типовой безопасности. Программы же на управляемом C++ должны гарантированно обладать указанным свойством. Однако, из-за того, что программы C++ могут содержать неуправляемый код, они не обязательно обладают свойством типовой безопасности. Нельзя производить арифметические операции с управляемыми указателями. Кроме того, нельзя приводить тип управляемого указателя к неуправляемому. Поэтому можно доказать безопасность только тех программ на C++, которые содержат лишь управляемые код и данные [Управляемый C++ может генерировать код, гарантированно обладающий свойством типовой безопасности, если избегать использования некоторых особенностей языка, таких, как неуправляемые указатели или приведение типов. Для проверки типовой безопасности сборки можно использовать утилиту Pevenfy.exe].

Тем не менее, любая программа на C++, в которой выполняются арифметические действия над неуправляемыми указателями или приводятся типы управляемых указателей к неуправляемым, является потенциально опасной.

Следующая программа является примером небезопасного кода на C++, в котором выполняется приведение указателя pumc на неуправляемый объект к указателю на переменную типа j_nt. В этом случае подобная операция не является опасной, но в общем случае ее выполнение может представлять опасность. Затем выполняется арифметическое действие над указателем на объект, которое уже в этом примере небезопасно, так как получающийся в результате указатель не указывает на какой-либо объект.

Еще ниже в этом примере, в закомментированных строках, те же действия совершаются над управляемым указателем pumc. Если бы строки были не закомментированы, компилятор выдал бы сообщение об ошибке.

// Unmanaged.срр
# using <mscorllib.dll>
class UnmanagedClass
// класс UnmanagedClass
{
public:
int i;
};
_gc class ManagedClass
// класс сборщика мусора ManagedClass
{
public:
int i;
};
void main(void)
{
UnmanagedClass *pumc = new UnmanagedClass;
pumc › i = 10;
int * pi = (int *}pumc; // Опасно приведение указателя
pi = (int *)(pumc+1); // Опасность: арифметика над указателями
ManagedClass *pmc = new ManagedClass; pmc › i = 10;
//pi = (int *)pmc; // Ошибка: приведение _gc //(сборщик мусора) * к *
//pi = (int *)(pmc+1); // Ошибка, арифметика над _gc // (сборщик мусора) *
}
Если Вы заметили ошибку, выделите, пожалуйста, необходимый текст и нажмите CTRL + Enter, чтобы сообщить об этом редактору.