C++ 什么是类型安全,什么是“类型安全”的替代方案?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2140369/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
What is type safety and what are the "type safe" alternatives?
提问by Dr Deo
Possible Duplicates:
What is Type-safe?
What is type-safety?
I was reading about c++ vectors and it was mentioned that memcpy
and printf
functions from C are not type safe. Article here: http://en.wikipedia.org/wiki/Vector_(C%2B%2B).
我正在读约C ++矢量和中提到,memcpy
和printf
从C函数不是类型安全。文章在这里:http: //en.wikipedia.org/wiki/Vector_(C%2B%2B)。
Question: In simple English, what is type safety and what are the "type safe" alternatives?
问题:用简单的英语来说,什么是类型安全,什么是“类型安全”的替代方案?
回答by Chris Jester-Young
Type safety means that the compiler can check whether you're using the right types. For example, if you're using printf
, you could accidentally crash your program by writing this:
类型安全意味着编译器可以检查您是否使用了正确的类型。例如,如果您正在使用printf
,您可能会通过编写以下内容意外崩溃您的程序:
printf("The meaning of life is %s", 42);
because 42 is an integer, not a string.
因为 42 是一个整数,而不是一个字符串。
回答by csl
Type safetymeans that the compiler will help check that you don't mix (incompatible) data types.
类型安全意味着编译器将帮助检查您没有混合(不兼容)数据类型。
For instance, when you call memcpy
, the function (and compiler) only sees two pointers in memory, and will happily start copying data. This means you can mix incompatible data types like this:
例如,当您调用 时memcpy
,函数(和编译器)只会看到内存中的两个指针,并且会很高兴地开始复制数据。这意味着您可以混合不兼容的数据类型,如下所示:
SomeClass a;
AnotherClass b;
memcpy((void*)&a, (void*)&b, sizeof(b));
There are many approaches to gaining type safety. You could use templates and make a wrapper around mempcy(), ensuring that the two pointers point to the same data type, or you could use other ways.
有很多方法可以获得类型安全。您可以使用模板并对 mempcy() 进行包装,确保两个指针指向相同的数据类型,或者您可以使用其他方式。
Since you are already using vectors from the STL, you are already using a more or less type safe implementation.
由于您已经在使用 STL 中的向量,因此您已经在使用或多或少的类型安全实现。
回答by t0mm13b
Type safety governs the usage of the compiler checking if the variable is of a right type. C is very loose on data type safety, for example, this is actually in the ANSI C standards, that states that type promotion will occur for data type char
, an example in this assignment will explain this,
类型安全控制编译器检查变量是否为正确类型的使用。C 对数据类型安全性非常松散,例如,这实际上在 ANSI C 标准中,规定数据类型将发生类型提升char
,此作业中的示例将解释这一点,
char ch = 32; /* that is a space character accordingly to ASCII */
int n = ch + 3;
Notice how the ch
variable gets 'promoted' to type int
. That is legitimate but warrants closer inspection if that is what you are implying.
注意ch
变量是如何“提升”到 type 的int
。这是合法的,但如果这是您的暗示,则需要仔细检查。
Compilers such as the C# compiler will not allow this to happen, that is the very reason why in C, there is a usage of cast's operator for example:
诸如 C# 编译器之类的编译器不允许这种情况发生,这就是为什么在 C 中使用 cast 运算符的原因,例如:
int n = (int)3.1415926535f;
Nit picky aside, that is a pi value, what happens, is that the value of n
will be 3.
除了挑剔之外,这是一个 pi 值,会发生什么,值n
将是 3。
The above serves to illustrate the type safety and that C is very loose on this regard.
以上用于说明类型安全性,并且 C 在这方面非常松散。
Type safety in modern languages is more strict, such as Java, C#, in order to constrain the usage and meaning of the variables. PHP is an excellent example of loose typing, where you could do this:
现代语言中的类型安全更加严格,例如Java、C#,以限制变量的用法和含义。PHP 是松散类型的一个很好的例子,你可以这样做:
$myvar = 34;
$myvar = $myvar + "foo";
is $myvar
an integer, or is it a floating point or is it a string. The type safety here is not very clear on what is the intention which can lead to bugs and a happy debugging session trying to figure out what is happening.
是$myvar
整数,还是浮点数,还是字符串。这里的类型安全不是很清楚可能导致错误和愉快的调试会话试图找出发生了什么的意图。
Hope this helps
希望这可以帮助
回答by Thomas
Since you were on Wikipedia anyway: Type safety.
反正你是在维基百科上:类型安全。
Type safety means, roughly speaking, that the language prohibits you from accidentally mixing up your types.
粗略地说,类型安全意味着该语言禁止您不小心混淆您的类型。
memcpy
is not type-safe because you can easily copy the memory of some int
into a char
array and end up with meaningless data. printf
is not type safe because you can provide a %i
format specifier with a string; again, the string will be interpreted as an int
and you'll end up with garbage. (Incidentally, the VC++ compiler doescheck the format string in some situations.)
memcpy
不是类型安全的,因为您可以轻松地将某些内存复制int
到char
数组中并最终得到无意义的数据。printf
不是类型安全的,因为您可以提供%i
带有字符串的格式说明符;再次,字符串将被解释为 anint
并且你最终会得到垃圾。(顺便说一句,VC++ 编译器在某些情况下会检查格式字符串。)
std::vector<T>
is type-safe, because it only allows you to put values of the given type T
into it. (You can do explicit typecasts, of course, but the point is that you have to be explicitabout doing something that's not type safe).
std::vector<T>
是类型安全的,因为它只允许您将给定类型的值T
放入其中。(当然,您可以进行显式类型转换,但关键是您必须明确执行类型不安全的操作)。
回答by UncleBens
"Type safety" means that the compiler checks that you are doing the right things with the right types (e.g triggers a compiler error if you attempt to treat a Banana as an Orange, or give a string to a function expecting to output an integer).
“类型安全”意味着编译器会检查您是否使用正确的类型做正确的事情(例如,如果您尝试将 Banana 视为 Orange,或者将字符串提供给期望输出整数的函数,则会触发编译器错误) .
Type safety (mostly) goes right out of the window when void*
comes into the picture - it is a pointer that can point to anything (completely unaware of the types involved), and the language leaves going about with it completely in the programmers hands (for example, a void*
isn't mostly good for anything except for being cast back to the original type; it can represent anything, but you have to know what it is before you can use it).
当void*
进入图片时,类型安全(大多数情况下)会直接离开窗口- 它是一个可以指向任何东西的指针(完全不知道所涉及的类型),并且语言完全掌握在程序员手中(对于例如,void*
除了被强制转换回原始类型之外,a对任何事情都没有好处;它可以代表任何东西,但在使用它之前你必须知道它是什么)。
Type unsafety also comes to play with variadic functions like printf (the compiler doesn't care how many arguments there are and what their types are - again it is up to the caller to make sure that the format string matches the arguments and their types).
类型不安全也与 printf 等可变参数函数有关(编译器不关心有多少参数以及它们的类型 - 同样由调用者确保格式字符串与参数及其类型匹配) .
Type-safe alternative to memcpy (for arrays and containers) could be std::copy
in <algorithm>
- it may be implemented in terms of memmove if all involved types satisfy certain requirements, otherwise it performs assignments - with some classes you can break certain invariants if you bypass their public interface and just go and move / copy them around in memory (for example, I suppose any class with a non-trivial copy constructor is going to misbehave if you make copies of it with memcpy).
类型安全的替代品的memcpy(阵列和容器)可以std::copy
在<algorithm>
-它可能的memmove的角度来实现的,如果所有涉及的类型都满足一定的要求,否则执行任务-与某些类,你可以绕过他们的公众,如果你打破某些不变接口,然后在内存中移动/复制它们(例如,我想如果你用 memcpy 复制它,任何具有非平凡复制构造函数的类都会行为不端)。
Type-safe alternative to C I/O routines are iostreams (and if you want the benefits of the format string, boost::format
).
CI/O 例程的类型安全替代方案是 iostreams(如果您想要格式字符串的好处,请使用boost::format
)。
回答by Liz Albin
"Type safety" is using a "type system" to ensure that errors are not propagated within programs. For example, without type safety, it might be possible to (silently) add a string type to floating point type in some undesirable way.
“类型安全”使用“类型系统”来确保错误不会在程序中传播。例如,在没有类型安全的情况下,可能会(悄悄地)以某种不受欢迎的方式将字符串类型添加到浮点类型。
In the instances you're talking about, memcpy()and printf(), the lack of type safety is due to the how the functions treat their arguments. For example, with memcpy(arg1, arg2, len), the lenbytes starting at memory address arg2will be copied to memory address arg1, regardless of how many bytes arg1points to, potentially overwriting other portions of your program.
在您谈论的实例memcpy()和printf() 中,缺乏类型安全是由于函数如何处理它们的参数。例如,对于memcpy(arg1, arg2, len),无论arg1指向多少字节,从内存地址arg2开始的len字节都将被复制到内存地址arg1,这可能会覆盖程序的其他部分。
For type safe alternatives, look into constructorsand cout.
In fact, look into the entire C++ FAQ Lite
回答by dsimcha
It means that the compiler will generate no warning if you try to use a type in a way that doesn't make sense for that type. For example, the following is undefined behavior and in practice will copy the bits of a pointer into the bits of a float, where they make absolutely no sense. If sizeof(char*)
> sizeof(float)
, it will overwrite whatever memory locations happen to be just above where f
lives.
这意味着如果您尝试以对该类型没有意义的方式使用类型,编译器将不会生成警告。例如,以下是未定义的行为,在实践中会将指针的位复制到浮点数的位中,在那里它们完全没有意义。如果sizeof(char*)
> sizeof(float)
,它将覆盖恰好位于f
居住位置上方的任何内存位置。
float f;
char *c = someString();
memcpy(&f, &c, sizeof(char*));
回答by Alexander Gessler
Type safety refers to a coding paradigm that enforces every variable to have a dedicated type at compilation time, for example int a = 4; double d = 100.0; struct ms {char s;} mystruct;
The type of a variable is never 'lost'. If you want to change its type from a to b, an explicit or implicit conversion must be defined.
类型安全是指一种编码范式,它在编译时强制每个变量都具有专用类型,例如int a = 4; double d = 100.0; struct ms {char s;} mystruct;
变量的类型永远不会“丢失”。如果要将其类型从 a 更改为 b,则必须定义显式或隐式转换。
printf
is nottypesafe because you pass the arguments in a variadic argument list:
printf
是不是类型安全的,因为你传递参数的可变参数的参数列表:
float f = 1.f;
printf("This is a float: %f\nAnd this is a string: %s",f,f);
printf
does not know which kind of values she receives. The format string is used by the implementation to find out, but if the string is wrong, the implementation has no chance to find it out because there is no type information available at compile-time. The above printf
call is most likely to end up catastrophic - printf expects a string as second parameter, but gets a floating-point number.
printf
不知道她接受了什么样的价值观。实现使用格式字符串来查找,但如果字符串错误,则实现没有机会找到它,因为在编译时没有可用的类型信息。上面的printf
调用很可能会导致灾难性的结果—— printf 期望一个字符串作为第二个参数,但得到一个浮点数。
回答by Daniel Daranas
A short version of the answer:
答案的简短版本:
class Person;
person.DoSomething(); // This is type safe.
void * p = &person; // You can now start doing unsafe things with p.
You can't pass a Person to memcpy. It only knows and cares about memory. Bytes.
您不能将 Person 传递给 memcpy。它只知道和关心内存。字节。
回答by Hyman
The signature of memcpy function is
memcpy 函数的签名是
void *memcpy (void* destination, const void* source, size_t num);
so as you can see it doesn't assume anything about pointers involved with the copy, they are just pointers. So if for example you want to copy a range of ints
to a range of floats
compiler won't complain about that.
因此,正如您所看到的,它不假设与副本有关的指针有任何关系,它们只是指针。因此,例如,如果您想将一个范围复制ints
到一个范围内,floats
编译器就不会抱怨。
Type Safetyis a tool that helps developers to avoid certain errors by preventing some kind of erroneous code being compiled (and lately executed). It analyzes semantic aspect of source code to check if conversion between types and types in general are cohoerent.
类型安全是一种工具,它通过防止某种错误代码被编译(和最近执行)来帮助开发人员避免某些错误。它分析源代码的语义方面,以检查类型和类型之间的转换是否一致。
What does that mean? It means that if your program passes the type checking phaseyou can be sure not to generate CERTAIN KINDof errors at run-time.
这意味着什么?这意味着如果您的程序通过了类型检查阶段,您可以确保不会在运行时生成某些类型的错误。
Of course sometimes you need to force this check not to be done, that's why you can use casts to force things to be what you want. Think about another example, malloc
: it is defined to be
当然,有时您需要强制不执行此检查,这就是为什么您可以使用强制转换来强制事情成为您想要的。再想想另一个例子malloc
:它被定义为
void* malloc (size_t size);
so when you want to allocate a pointer to floats
for example you do:
所以当你想分配一个指针时floats
,例如你这样做:
float* ptr = (float*)malloc(sizeof(float*)*COUNT);
You are forced to cast the result of the function to be float*
otherwise the typecheck will find an assign of a void*
to a float*
but void*
is too generic to be assigned so: TYPE CHECK FAIL!
你不得不投功能的结果是float*
,否则类型检测,将找到的一个分配void*
到一个float*
,但void*
太普通了被分配这样:类型检查失败!
That's why memcpy
is not type-safe. It doesn't check anything, it just copy from a pointer to another pointer.
这就是为什么memcpy
不是类型安全的。它不检查任何东西,它只是从一个指针复制到另一个指针。