自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

C語言邊角料4:利用_Pragma來溫柔的廢棄API

開發(fā) 后端
這篇小短文就來聊一聊利用_Pragma來溫柔的廢棄API,希望能夠幫助到你!

[[389822]]

一、前言

想象一下這個工作場景:你在為一個項目寫一個功能庫,別人調(diào)用庫中提供的函數(shù),后來你發(fā)現(xiàn)庫里的函數(shù)A是多余的。

具有完美情節(jié)的你,就是想把這個函數(shù)A廢棄掉,此時肯定是不能直接刪掉,因為你不知道別人在多少個地方調(diào)用了這個函數(shù)。

這種情況如何處理比較好呢?

這篇小短文就來聊一聊這個問題。

二、操作過程

1. 第一個版本的庫

測試文件只有 3 個:api.h, api.c 和 main.c

  • api.h 和 api.c: 庫文件,編譯得到 libapi.so;
  • main.c:生成可執(zhí)行程序,利用了上面生成的庫 libapi.so;

api.h 文件內(nèi)容:聲明了 2 個函數(shù)。


api.c 文件內(nèi)容:定義了 2 個函數(shù)。


編譯得到庫文件 libapi.so。編譯指令:

  1. gcc -fPIC -shared api.c -o libapi.so 

main.c 文件內(nèi)容:


編譯得到可執(zhí)行文件:

  1. gcc main.c -o main -L./ -Wl,-rpath=./ -lapi 

以上代碼的簡單程度,等價于 helloworld 了。

2. 第二個版本的庫

現(xiàn)在,你覺得 init 這個函數(shù)是多余的,想把它去掉,可以這么來修改。

api.c 文件中,把 init() 函數(shù)刪除掉。

api.h 文件內(nèi)容改為如下:


關(guān)鍵代碼是這一行:

  1. #define init()   (1) API_DEPRECATED 

既然 api.c 文件已經(jīng)把這個函數(shù)刪除了,但是 main.c 文件中又調(diào)用了這個函數(shù),因此以宏定義的形式提供 init 這個符號。

也就是說:

在第一個版本中,main.c 文件中的 init 是一個函數(shù),被編譯器處理,在鏈接階段從 libapi.so 庫中找到這個函數(shù)的地址;

在第二個版本中,init 被定義成宏,在預(yù)處理階段被替換成后面的 (1) API_DEPRECATED。

  • (1) 是在宏替換時的表達式。因為這個函數(shù)可能被用在 if 條件判斷中,因此需要返回一個值。
  • API_DEPRECATED 是另一個宏定義,擴展開來后就是讓編譯器在編譯可執(zhí)行程序時,打印出一段提示信息。

在編譯可執(zhí)行文件時,編譯器輸出下面的這段話:

  1. gcc main.c -o main -L./ -Wl,-rpath=./ -lapi 

 

這樣就達到了最初的目的!也就是提示使用者:這個函數(shù)已經(jīng)被廢棄了,最好別用它!

三 _Prama 其他用法

_Pragma 類似于 Microsoft 特定的 __pragma 關(guān)鍵字,只不過它是標準的一部分。它是在 C99 中為 C 引入的。對于 c + +,它是在 c + + 11 中引入的。它允許將指令放入宏定義中。

1. 處理頭文件重復包含

在頭文件中,為了防止被重復包含,一般有 3 種處理方式:

(1) 第一種處理方式:

  1. #ifdef   MY_API 
  2. #define  MY_API 
  3.  
  4. // 頭文件內(nèi)容 
  5.  
  6. #endif 

(2) 第二種處理方式

  1. #pragma once 
  2.  
  3. // 頭文件內(nèi)容 

以上這 2 種方式都可以防止同一個頭文件被重復包含,但是還是有一些區(qū)別的。

第一種方式:預(yù)處理器還是需要去搜尋文件,然后打開文件,讀取文件的內(nèi)容之后,檢查 MY_API 是否已經(jīng)被定義過。

第二種方式:能加快編譯速度,因為這是一種高端的機制;編譯器會自動比對文件名,而不需要在頭文件去判斷 #ifndef 和 #endif,這樣就省去了中間的搜尋、打開和讀取操作。

(3) 第三種處理方式

  1. _Pragma("once"

這種方式與第二種方式的區(qū)別是:

  • #pragma :是一條預(yù)處理的指令,用來向編譯器傳達語言標準以外的一些信息,不能使用在宏中;
  • _Pragma :是一個操作符,屬于語言的標準,因此可以嵌套在宏中,就像上面示例中那樣;

#pragma 是編譯器的擴展,也就是說它是由編譯器來決定的,也許編譯器A支持,但是編譯器B就不一定支持了,雖然這種可能性比較小。

_Pragma 操作符是語言層面的標準,既然是標準,那么編譯器就必須要遵循標準,所以也推薦使用這種方式。

記得侯杰老師在 C++ 的視頻課程中說到:我們寫代碼,不僅僅要保證功能上的正確,而且要把代碼寫的很大氣!我感覺用 _Pragma 可能比 #ifndef 更大氣一些。

2. 輸出編譯信息

  1. #pragma message("the #pragma way"
  2. _Pragma ("message( \"the _Pragma way\")"

 上面兩行的內(nèi)容輸出信息是一樣的,需要注意的是嵌套的雙引號需要用反斜線去轉(zhuǎn)義。

 

責任編輯:姜華 來源: IOT物聯(lián)網(wǎng)小鎮(zhèn)
相關(guān)推薦

2021-03-22 11:27:06

C語言Peterson(皮特互斥鎖

2021-03-24 08:02:58

C語言

2021-03-30 11:33:03

C語言頭文件開發(fā)

2021-05-11 11:31:52

C語言類型指針

2021-01-31 11:47:08

C語言SetjmpLongjmp

2015-07-09 09:35:26

2021-03-26 11:02:20

Python自然語言API

2009-08-19 16:50:32

Visual C#C#語言特性

2024-03-19 07:00:00

C++編程pragma

2023-04-21 19:01:55

2022-02-13 23:51:44

DeepfenceLog4j2漏洞

2009-10-21 13:39:08

UACWindows 7微軟

2021-08-25 23:03:58

區(qū)塊鏈數(shù)據(jù)安全

2010-01-15 17:38:37

C++語言

2024-11-05 14:45:26

2009-07-31 17:14:19

C#語言Web程序

2013-10-22 10:38:43

C++編程語言

2009-08-06 18:03:21

C#相對路徑

2011-11-25 13:30:09

JavaXPath

2019-11-13 11:52:46

區(qū)塊鏈API比特幣
點贊
收藏

51CTO技術(shù)棧公眾號