Подтвердить что ты не робот

Что такое безопасность типов и каковы альтернативы типа "безопасный"?

Возможные дубликаты:
Что такое безопасный тип?
Что такое безопасность типов?

Я читал о векторах С++, и было упомянуто, что функции memcpy и printf из C не безопасны для типов. Статья здесь: http://en.wikipedia.org/wiki/Vector_(C%2B%2B).

Вопрос: На простом английском языке, что такое безопасность типов и какие альтернативы типа "безопасны"?

4b9b3361

Ответ 1

Тип безопасности означает, что компилятор может проверить, используете ли вы правильные типы. Например, если вы используете printf, вы можете случайно свернуть свою программу, написав это:

printf("The meaning of life is %s", 42);

потому что 42 - целое число, а не строка.

Ответ 2

Тип безопасности означает, что компилятор поможет проверить, что вы не смешиваете (несовместимые) типы данных.

Например, когда вы вызываете memcpy, функция (и компилятор) видит только два указателя в памяти и с радостью начнет копировать данные. Это означает, что вы можете смешивать несовместимые типы данных следующим образом:

SomeClass a;
AnotherClass b;
memcpy((void*)&a, (void*)&b, sizeof(b));

Существует множество подходов к обеспечению безопасности типов. Вы можете использовать шаблоны и создать оболочку mempcy(), гарантируя, что два указателя указывают на один и тот же тип данных, или вы можете использовать другие способы.

Поскольку вы уже используете векторы из STL, вы уже используете безопасную реализацию более или менее типа.

Ответ 3

Тип безопасности определяет использование проверки компилятором, если переменная имеет правильный тип. C очень свободен в отношении безопасности типа данных, например, это фактически соответствует стандарту ANSI C, в котором говорится, что для типа данных char будет выполняться продвижение типа, пример этого назначения объяснит это,

char ch = 32; /* that is a space character accordingly to ASCII */
int n = ch + 3;

Обратите внимание, как переменная ch получает "продвигаемый" для ввода int. Это законно, но требует более тщательной проверки, если это то, что вы подразумеваете.

Компиляторы, такие как компилятор С#, не позволят этому произойти, именно поэтому в C используется использование оператора трансляции, например:

int n = (int)3.1415926535f;

Отбросить нит в сторону, то есть значение pi, что происходит, то, что значение n будет равно 3.

Вышеуказанное служит для иллюстрации безопасности типа и что C в этом отношении очень ослаблен.

Тип безопасности в современных языках более строгий, например Java, С#, чтобы ограничить использование и значение переменных. PHP - отличный пример быстрого набора текста, где вы можете это сделать:

$myvar = 34;
$myvar = $myvar + "foo";

является $myvar целым числом или является плавающей точкой или является строкой. Безопасность типов здесь не совсем ясна, какова цель, которая может привести к ошибкам и счастливой сессии отладки, пытаясь понять, что происходит.

Надеюсь, что это поможет

Ответ 4

Поскольку вы все еще были в Википедии: Тип безопасности.

Тип безопасности означает, грубо говоря, что язык запрещает вам случайно смешивать ваши типы.

memcpy не является безопасным для типов, так как вы можете легко скопировать память некоторого int в массив char и в итоге получить бессмысленные данные. printf не является безопасным по типу, поскольку вы можете указать спецификатор формата %i со строкой; снова строка будет интерпретирована как int, и вы получите мусор. (Кстати, компилятор VС++ проверяет строку формата в некоторых ситуациях.)

std::vector<T> является безопасным по типу, поскольку он позволяет вам вставлять в него значения данного типа T. (Конечно, вы можете делать явные приемы типов, но дело в том, что вы должны быть явными о том, чтобы делать что-то, что не должно быть безопасным).

Ответ 5

"Тип безопасности" означает, что компилятор проверяет, что вы делаете правильные вещи с правильными типами (например, запускает ошибку компилятора, если вы пытаетесь обработать Банану как оранжевую или передать строку функции, ожидающей выхода целое число).

Тип безопасности (в основном) выходит прямо из окна, когда на картинке появляется void* - это указатель, который может указывать на что-либо (совершенно не подозревая о задействованных типах), и язык полностью исчезает в командах программистов (например, void* не в основном хорош для чего-либо, кроме того, что он возвращается к исходному типу, он может представлять что угодно, но вы должны знать, что это, прежде чем вы сможете его использовать).

Тип unsafety также включает в себя различные вариационные функции, такие как printf (компилятор не заботится о том, сколько аргументов существует и каковы их типы), опять же, до вызывающего пользователя, чтобы убедиться, что строка формата соответствует аргументам и их типы).

Типобезопасная альтернатива memcpy (для массивов и контейнеров) может быть std::copy в <algorithm> - она ​​может быть реализована в терминах memmove, если все задействованные типы удовлетворяют определенным требованиям, в противном случае она выполняет присвоения - с некоторыми классами вы могут обрывать некоторые инварианты, если вы обходите их публичный интерфейс и просто переходите и перемещаете/копируете их в памяти (например, я полагаю, что любой класс с нетривиальным конструктором копий будет ошибочным, если вы сделаете его копии с помощью memcpy).

Типичная альтернатива C-процедурам ввода-вывода - это iostreams (и если вы хотите использовать преимущества строки формата boost::format).

Ответ 6

"Безопасность типа" использует "систему типов", чтобы гарантировать, что ошибки не распространяются внутри программ. Например, без безопасности типа может быть возможно (тихо) добавить тип строки в тип с плавающей запятой некоторым нежелательным способом.

В случаях, о которых вы говорите, memcpy() и printf(), отсутствие безопасности типов связано с тем, как функции обрабатывают свои аргументы. Например, с memcpy (arg1, arg2, len) младшие байты, начинающиеся с адреса памяти arg2, будут скопированы в адрес arg1, независимо от того, сколько байтов arg1 указывает на потенциальную перезапись других частей вашей программы.

Для типов безопасных альтернатив рассмотрите конструкторы и cout.

Фактически, просмотрите весь С++ FAQ Lite

Ответ 7

Это означает, что компилятор не будет генерировать никаких предупреждений, если вы попытаетесь использовать тип таким образом, чтобы это не имело смысла для этого типа. Например, следующее поведение undefined и на практике копирует биты указателя в биты float, где они не имеют абсолютно никакого смысла. Если sizeof(char*) > sizeof(float), он перезапишет все места памяти, находящиеся выше, где f живет.

float f;
char *c = someString();
memcpy(&f, &c, sizeof(char*));

Ответ 8

Тип безопасности относится к парадигме кодирования, которая обеспечивает, чтобы каждая переменная имела выделенный тип во время компиляции, например 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 ожидает строку как второй параметр, но получает число с плавающей запятой.

Ответ 9

Короткий вариант ответа:

class Person;

person.DoSomething(); // This is type safe.

void * p = &person; // You can now start doing unsafe things with p.

Вы не можете передать Person в memcpy. Он знает и заботится о памяти. Байты.

Ответ 10

Подпись функции memcpy

void *memcpy (void* destination, const void* source, size_t num);

так как вы можете видеть, что он не предполагает ничего о указателях, связанных с копией, они просто указатели. Поэтому, если вы хотите скопировать диапазон ints в диапазон floats, компилятор не будет жаловаться на это.

Безопасность типов - это инструмент, который помогает разработчикам избегать определенных ошибок, предотвращая компиляцию некорректного кода (и в последнее время выполняется). В нем анализируется семантический аспект исходного кода, чтобы проверить, являются ли конверсии между типами и типами в общем случае когерентными.

Что это значит? Это означает, что если ваша программа проходит фазу проверки типа, вы можете быть уверены, что не должны генерировать CERTAIN KIND ошибок во время выполнения.

Конечно, иногда вам нужно заставить эту проверку не делать, поэтому вы можете использовать броски, чтобы заставить вещи быть тем, что вы хотите. Подумайте о другом примере malloc: он определен как

void* malloc (size_t size);

поэтому, если вы хотите выделить указатель на floats, например:

float* ptr = (float*)malloc(sizeof(float*)*COUNT);

Вы вынуждены придать результат функции float*, иначе typecheck найдет назначение void* на float*, но void* будет слишком общим для назначения: ТИП ПРОВЕРКА НЕИСПРАВНОСТИ!

Вот почему memcpy не безопасен для типов. Он ничего не проверяет, он просто копирует указатель на другой указатель.