什么是类型安全,C/C++是类型安全的吗?

【1】首先:C/C++不是类型安全的语言。
类型安全是指同一段内存在不同的地方,会被强制要求使用相同的办法来解释(内存中的数据是用类型来解释的)。
//类型安全性意味着编译器将在编译时验证类型,如果尝试将错误的类型分配给变量,则抛出错误。
Java语言是类型安全的,除非强制类型转换。
C语言不是类型安全的,因为同一段内存可以用不同的数据类型来解释,比如1用int来解释就是1,用boolean来解释就是true。

------------------------------------------------

什么是类型安全?
       类型安全很大程度上可以等价于内存安全,类型安全的代码不会试图访问自己没被授权的内存区域。“类型安全”常被用来形容编程语言,其根据在于该门编程语言是否提供保障类型安全的机制;有的时候也用“类型安全”形容某个程序,判别的标准在于该程序是否隐含类型错误。类型安全的编程语言与类型安全的程序之间,没有必然联系。绝对类型安全的编程语言暂时还没有。

C语言的类型安全:
       C只在局部上下文中表现出类型安全,比如试图从一种结构体的指针转换成另一种结构体的指针时,编译器将会报告错误,除非使用显式类型转换。然而,C中相当多的操作是不安全的。以下是两个十分常见的例子:

<1>printf格式输出

int main()
{
    printf("%d\n",10);
    system("pause");
    return 0;
}

  上面的代码很简单,printf函数中,%d与10匹配,结果正确。但如果稍作修改:

int main()
{
    printf("%f\n",10);
    system("pause");
    return 0;
}

%f浮点数与10并不匹配,但是编译通过,执行也没报错,但是结果却是:
0.000000
更进一步,把%f修改为%s,编译通过,执行将报错Access Violation。

<2>malloc函数的返回值
          malloc是C中进行内存分配的函数,它的返回类型是void*即空类型指针,常常有这样的用法char* pStr=(char*)malloc(100*sizeof(char)),这里明显做了显式的类型转换。类型匹配尚且没有问题,但是一旦出现int* pInt=(int*)malloc(100*sizeof(char))就很可能带来一些问题,而这样的转换C并不会提示错误。

C++的类型安全:
如果C++使用得当,它将远比C更有类型安全性。相比于C,C++提供了一些新的机制保障类型安全:
(1)操作符new返回的指针类型严格与对象匹配,而不是void*;
(2)C中很多以void*为参数的函数可以改写为C++模板函数,而模板是支持类型检查的;
(3)引入const关键字代替#define constants,它是有类型、有作用域的,而#define constants只是简单的文本替换;
(4)一些#define宏可被改写为inline函数,结合函数的重载,可在类型安全的前提下支持多种类型,当然改写为模板也能保证类型安全;
(5)C++提供了dynamic_cast关键字,使得转换过程更加安全,因为dynamic_cast比static_cast涉及更多具体的类型检查。

  即便如此,C++也不是绝对类型安全的编程语言。如果使用不得当,同样无法保证类型安全。比如下面两个例子:

int i=5;
void* pInt=&i;
double d=(*(double*)pInt);
cout<<d<<endl;

输入结果不是5,而意想不到的结果:-9.25596e+061。又比如:

#include<iostream>
using namespace std;
class Parent
{
};
class Child1:public Parent
{
public:
    int i;
    Child1(int e):i(e)
    {
    }
};
class Child2:public Parent
{
public:
    double d;
    Child2(double e):d(e)
    {
    }
};
int main()
{
    Child1 c1(5);
    Child2 c2(4.1);
    Parent* pp;
    Child1* pc1;
 
    pp=&c1;
    pc1=(Child1*)pp;  //#1 强制转换,由于类型仍然为Child1*,不造成错误
    cout<<pc1->i<<endl;
 
    pp=&c2;
    pc1=(Child1*)pp;  //#2 强制转换,且类型发生变化,将造成错误
    cout<<pc1->i<<endl;
    system("pause");
    return 0;
}

       上面两个例子之所以引起类型不安全的问题,是因为程序员使用不得当。第一个例子用到了空类型指针void*,第二个例子则是在两个类型指针之间进行强制转换。因此,想保证程序的类型安全性,应尽量避免使用空类型指针void*,尽量不对两种类型指针做强制转换
 

  • 4
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值