Безопасность типа означает, что компилятор поможет проверить, что вы не смешиваете (несовместимые) типы данных.
Например, когда вы звоните memcpy
, функция (и компилятор) видит только два указателя в памяти, и будет счастливо начнет копирование данных. Это означает, что вы можете смешивать несовместимые типы данных, такие как это:
SomeClass a;
AnotherClass b;
memcpy((void*)&a, (void*)&b, sizeof(b));
Есть много подходов к получению безопасности типов. Вы можете использовать шаблоны и сделать обертку вокруг Mempcy (), гарантируя, что два указателя указывают на тот же тип данных, или вы можете использовать другие способы.
Поскольку вы уже используете векторы от STL, вы уже используете более или менее безопасную реализацию типа.
Краткая версия ответа:
class Person;
person.DoSomething(); // This is type safe.
void * p = &person; // You can now start doing unsafe things with p.
Вы не можете передать человека на мемкпи. Он только знает и заботится о памяти. Байты.
Безопасность типов регулирует использование компилятора, проверяющего, является ли переменная правильным типом. C очень слабо влияет на безопасность типов данных, например, в стандартах ANSI C, где указано, что продвижение типа происходит для типа данных char
, пример в этом присваивании объясняет это,
char ch = 32; /* that is a space character accordingly to ASCII */
int n = ch + 3;
Заметьте, как переменная ch
получает 'продвижение' к типу int
. Это законно, но требует более тщательного изучения, если вы на это намекаете.
Компиляторы, такие как компилятор Си#, не допустят этого, именно поэтому в Си используется оператор приведения, например:
int n = (int)3.1415926535f;
Nit picky в сторону, т.е. значение pi, что происходит, так это то, что значение n
будет 3.
Вышеуказанное служит иллюстрацией безопасности типа и того, что C в этом отношении очень шатко.
Безопасность типа в современных языках более строгая, например, Java, C#, чтобы ограничить использование и значение переменных. PHP является отличным примером свободного набора текста, где вы можете сделать это:
$myvar = 34;
$myvar = $myvar + "foo";
является $myvar
целым числом, или это плавающая точка, или это строка. Безопасность типов здесь не очень понятна, что является намерением, которое может привести к ошибкам и счастливой отладочной сессии, пытающейся выяснить, что происходит.
Надеюсь, это поможет
"Безопасность типа" - это использование "системы типов" для предотвращения распространения ошибок внутри программ. Например, без безопасности типов можно (молча) каким-то нежелательным образом добавить строковый тип к типу с плавающей точкой.
В случаях, о которых вы говорите, memcpy() и printf(), отсутствие безопасности типов связано с тем, как функции обрабатывают свои аргументы. Например, с помощью memcpy(arg1, arg2, len) байты len, начинающиеся по адресу памяти arg2, будут скопированы по адресу памяти arg1, независимо от того, на сколько байт arg1 указывает, потенциально перезаписывая другие части вашей программы.
Для поиска безопасных для типа альтернатив обратитесь к конструкторам и cout .
На самом деле, загляните во весь C++ FAQ Lite
«Безопасность типа» означает, что компилятор проверяет, что вы делаете правильные вещи с правильными типами (например, запускает ошибку компилятора, если вы пытаетесь лечить банан как оранжевый или дать строка в функцию, ожидаемую выводить целое число).
Тип Безопасность (в основном) идет прямо из окна, когда void *
входит в картинку - это указатель, который может указывать на что-либо (полностью не знает о типовых), а языковые листья Собираясь с ним полностью в программистах руки (например, void *
не в основном хороши для чего угодно, кроме как для того, чтобы быть обратно к исходному типу; это может представлять что-нибудь, но вы должны знать, что Это прежде чем вы можете использовать его).
Тип небезопасности также приходит к тому, чтобы играть с вариационными функциями, такими как printf (компилятор не заботится, сколько аргументов есть и какие их типы - опять же, это зависит от вызывающего абонента, чтобы убедиться, что строка формата соответствует аргументам и их типы).
Безопасная альтернатива типа MeMcpy (для массивов и контейнеров) может быть STD :: Copy
в
- это может быть реализовано в терминах MemMove, если все вовлечены типы Удовлетворяйте определенные требования, в противном случае он выполняет задания - с некоторыми классами вы можете сломать определенные инварианты, если вы обходите их общедоступный интерфейс и просто переходите и перемещаете / скопируете их в память (например, я полагаю, любой класс с нетривиальным конструктором копирования Собираюсь повзглянуться, если вы сделаете копии из него с мемкпином).
Тип-безопасная альтернатива в процедурах ввода-вывода C ввода / вывода - это ioStreams (и если вы хотите преимущества строки формата, Boost :: Format
).
Безопасность типа относится к парадигме кодирования, которая заставляет каждую переменную иметь выделенный тип во время компиляции, например int a = 4; double d = 100.0; struct ms {char s;} mystruct;
Тип переменной никогда не 'теряется'. Если вы хотите изменить ее тип с a на b, то должно быть определено явное или неявное приведение.
printf
является типом не, так как вы передаете аргументы в списке разнообразных аргументов:
float f = 1.f;
printf("This is a float: %f\nAnd this is a string: %s",f,f);
printf
не знает, какой тип значений она получает. Строка форматирования используется реализацией для выяснения, но если строка неверна, то реализация не имеет шансов ее выяснить, так как на этапе компиляции нет информации о типах. Вышеуказанный вызов printf
скорее всего закончится катастрофой - printf ожидает строку как второй параметр, но получает число с плавающей точкой.
Это означает, что компилятор не выдаст предупреждение, если вы попытаетесь использовать тип таким образом, что для этого типа нет смысла. Например, следующее является неопределенным поведением и на практике будет копировать биты указателя в биты флота, где они не имеют никакого смысла. Если sizeof(char*)
> sizeof(float)
, то он перезапишет все места памяти, которые окажутся чуть выше, чем f
.
float f;
char *c = someString();
memcpy(&f, &c, sizeof(char*));
Подпись функции MEMCPY IS
void *memcpy (void* destination, const void* source, size_t num);
, так как вы можете видеть, что она не принимает ничего о том, что указатели, связанные с копией, это только указатели. Таким образом, если бы, например, вы хотите скопировать диапазон ints
в диапазон , поплавков
Компилятор не будет жаловаться на это.
Безопасность типа - это инструмент, который помогает разработчикам избежать определенных ошибок, предотвращая компиляцию какой-то ошибочного кода (и в последнее время выполненного). Он анализирует семантический аспект исходного кода, чтобы проверить, если преобразование между типами и типовыми в целом являются кохорными.
Что это значит? Это означает, что если ваша программа проходит этап проверки типа , вы можете быть уверены, что не генерируют определенного вида ошибок во время выполнения.
Конечно, иногда вам нужно заставить эту проверку не быть сделано, поэтому вы можете использовать отказы, чтобы заставить то, что вы хотите. Подумайте о другом примере, MALLOC
: определено, что он определен
void* malloc (size_t size);
, поэтому, когда вы хотите выделить указатель на , например, поплавки
, например, вы делаете:
float* ptr = (float*)malloc(sizeof(float*)*COUNT);
Вы вынуждены бросить Результат функции float *
*
В противном случае TypeCheck найдет присвоение Void *
на поплавок *
, но void *
] слишком общий, чтобы быть назначенным так: Тип проверки не удалось!
Вот почему memcpy
не является безопасным типом. Это ничего не проверяет, он просто копирует с указателя на другой указатель.
нет никаких легких ответов или узоров, которые гарантируют успех. Точно так же, как ваш проверка стратегия, ваша точная стратегия обработки исключений характерна для вашей точной ситуации и является часто компромиссом между временем и полнотой. Существует некоторый хороший совет, который мы можем дать хотя:
Безопасность типа означает, что компилятор может проверить, используются ли нужные типы. Например, если вы используете printf
, вы можете случайно запустить программу, написав следующее:
printf("The meaning of life is %s", 42);
, потому что 42 является целым числом, а не последовательность.
Так как вы в любом случае были в Википедии: Тип безопасности .
Тип безопасных средств, грубо говоря, что язык запрещает вам случайное смешивание ваших типов.
MEMCPY
не является безопасным в типе, потому что вы можете легко скопировать память о некоторых INT
в массив CHAR
и в конечном итоге с бессмысленными данными. PrintF
не является безопасным типом, потому что вы можете предоставить спецификатор формата % I
со строкой; Опять же, строка будет интерпретироваться как INT
, и вы получите мусор. (Кстати, компилятор VC ++ проверяет строку формата в некоторых ситуациях.)
STD :: Vector
является типовым безопасным, потому что он только позволяет устанавливать значения Данный тип T
в него. (Конечно, вы можете сделать явные типовые погрузчики, но в том, что вы должны быть явным о том, чтобы делать что-то, что не типа безопасным).