C 是型別安全的嗎?

2021-08-25 14:00:15 字數 2163 閱讀 7465

什麼是型別安全?

型別安全很大程度上可以等價於記憶體安全,型別安全的**不會試圖訪問自己沒被授權的記憶體區域。「型別安全」常被用來形容程式語言,其根據在於該門程式語言是否提供保障型別安全的機制;有的時候也用「型別安全」形容某個程式,判別的標準在於該程式是否隱含型別錯誤。型別安全的程式語言與型別安全的程式之間,沒有必然聯絡。好的程式設計師可以使用型別不那麼安全的語言寫出型別相當安全的程式,相反的,差一點兒的程式設計師可能使用型別相當安全的語言寫出型別不太安全的程式。絕對型別安全的程式語言暫時還沒有。

c語言的型別安全

c只在區域性上下文中表現出型別安全,比如試圖從一種結構體的指標轉換成另一種結構體的指標時,編譯器將會報告錯誤,除非使用顯式型別轉換。然而,c中相當多的操作是不安全的。以下是兩個十分常見的例子:

(1)printf格式輸出

/* - print.cpp 

* version:1.1 

*/  

int main()  

上面的**很簡單,printf函式中,%d與10匹配,結果正確。

稍作修改:

/* - print.cpp 

* version:1.2 

*/  

int main()  

%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《輸入結果不是5,而意想不到的結果:-9.25596e+061。又比如:

#includeusing namespace std;  

class parent  

;  class child1:public parent  

};  

class child2:public parent  

};  

int main()  

{      child1 c1(5);  

child2 c2(4.1);  

parent* pp;  

child1* pc1;  

pp=&c1;  

pc1=(child1*)pp;  //#1 強制轉換,由於型別仍然為child1*,不造成錯誤  

cout51717986918

請按任意鍵繼續. . .

上面兩個例子之所以引起型別不安全的問題,是因為程式設計師使用不得當。第乙個例子用到了空型別指標void*,第二個例子則是在兩個型別指標之間進行強制轉換。因此,想保證程式的型別安全性,應盡量避免使用空型別指標void*,盡量不對兩種型別指標做強制轉換。

i 是執行緒安全的嗎?

i 不是原子操作,也就是說,它不是單獨一條指令,而是3條指令 3條彙編指令 1 從記憶體中把i的值取出來放到cpu的暫存器中 2 cpu暫存器的值 1 3 把cpu暫存器的值寫回記憶體 由於執行緒共享棧區,不共享堆區和全域性區,所以當且僅當 i 位於棧上是安全的,反之不安全 i也同理 因為如果是全域...

Servlet是執行緒安全的嗎?

servlet不是執行緒安全的。要解釋為什麼servlet為什麼不是執行緒安全的,需要了解servlet容器 即tomcat 使如何響應http請求的。當tomcat接收到client的http請求時,tomcat從執行緒池中取出乙個執行緒,之後找到該請求對應的servlet物件並進行初始化,之後呼...

servlet是執行緒安全的嗎

servlet 預設是單例模式,在web 容器中只建立乙個例項,所以多個執行緒同時訪問servlet的時候,servlet是執行緒不安全的。那麼 web 容器能為每個請求建立乙個servlet的例項 增加了系統的消耗 嗎?當然是可以的,只要servlet實現singlethreadmodel介面,就...