1. 程式人生 > >glibc之資料型別定義分析

glibc之資料型別定義分析

  本文主要涉及到的庫檔案位於/usr/include/bits目錄下,檔案包括wordsize.h,types.h,typesizes.h 等檔案。

  wordsize.h中主要定義了當前機器的字大小。內容如下:

  ...

  #define __WORDSIZE  32

  ...

  這裡的巨集應該是安裝系統的時候,確定的機器字的大小,然後才生成對應的巨集。這個巨集會在types.h中作為判定條件,從而定義相應資料型別。我們可以看下types.h檔案有如下內容:

   99 #define __S16_TYPE      short int
100 #define __U16_TYPE      unsigned short int
101 #define __S32_TYPE      int


102 #define __U32_TYPE      unsigned int
103 #define __SLONGWORD_TYPE    long int
104 #define __ULONGWORD_TYPE    unsigned long int

//以上型別定義與機器字長度無關
105 #if __WORDSIZE == 32
106 # define __SQUAD_TYPE       __quad_t
107 # define __UQUAD_TYPE       __u_quad_t
108 # define __SWORD_TYPE       int
109 # define __UWORD_TYPE       unsigned int
110 # define __SLONG32_TYPE     long int
111 # define __ULONG32_TYPE     unsigned long int
112 # define __S64_TYPE     __quad_t
113 # define __U64_TYPE     __u_quad_t
114 /* We want __extension__ before typedef's that use nonstandard base types
115    such as `long long' in C89 mode.  */
116 # define __STD_TYPE     __extension__ typedef //如果機器為32位,我們需要使用擴充套件資料型別定義巨集

117 #elif __WORDSIZE == 64
118 # define __SQUAD_TYPE       long int
119 # define __UQUAD_TYPE       unsigned long int
120 # define __SWORD_TYPE       long int
121 # define __UWORD_TYPE       unsigned long int
122 # define __SLONG32_TYPE     int
123 # define __ULONG32_TYPE     unsigned int
124 # define __S64_TYPE     long int
125 # define __U64_TYPE     unsigned long int
126 /* No need to mark the typedef with __extension__.   */
127 # define __STD_TYPE     typedef

//如果機器為64位,我們不需要在typedef前加擴充套件巨集 __extension__,後面的__STD_TYPE 即表示typedef
128 #else
129 # error
130 #endif

上面的# define __SQUAD_TYPE       __quad_t表示當機器為32位,但是又要表示64位資料時,我們可以通過如下方法定義:

 /* quad_t is also 64 bits.  */
 52 #if __WORDSIZE == 64
 53 typedef long int __quad_t;
 54 typedef unsigned long int __u_quad_t;
 55 #elif defined __GLIBC_HAVE_LONG_LONG
 56 __extension__ typedef long long int __quad_t;
 57 __extension__ typedef unsigned long long int __u_quad_t;
 58 #else //32位機器
 59 typedef struct
 60 {
 61   long __val[2];
 62 } __quad_t;
 63 typedef struct
 64 {
 65   __u_long __val[2];
 66 } __u_quad_t;

 67 #endif

131 #include <bits/typesizes.h> /* Defines __*_T_TYPE macros.  */

//將typesizes.h包含進來,因為裡面通過定義了所有的 __*_T_TYPE巨集,而這些巨集都是下面的型別定義的基礎


135 __STD_TYPE __UID_T_TYPE __uid_t;    /* Type of user identifications.  */
136 __STD_TYPE __GID_T_TYPE __gid_t;    /* Type of group identifications.  */
143 __STD_TYPE __PID_T_TYPE __pid_t;    /* Type of process identifications.  */
155 __STD_TYPE __KEY_T_TYPE __key_t;    /* Type of an IPC key.  */

注意這裡的__STD_TYPE = typedef 不再是巨集定義,而是型別定義

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

我們可以檢視typesizes.h檔案,內容如下:

  1 /* bits/typesizes.h -- underlying types for *_t.  Generic version.

       這個檔案用來定義類似於*_t的基本型別(underlying type)

        .....
  2  */
 19
 20 #ifndef _BITS_TYPES_H
 21 # error "Never include <bits/typesizes.h> directly; use <sys/types.h> instead."
 22 #endif
 23
 24 #ifndef _BITS_TYPESIZES_H
 25 #define _BITS_TYPESIZES_H   1
 26
 27 /* See <bits/types.h> for the meaning of these macros.  This file exists so
 28    that <bits/types.h> need not vary across different GNU platforms. 

         巨集定義參考types.h中的巨集定義,如__S32_TYPE 這個是在types.h中定義的。

         #define __S32_TYPE      int

        至於為什麼要這麼交叉定義,是為了使types.h不因為平臺而發生變化。

        因為,如果不同的平臺的話,我們只需要改變typesizes.h就可以了。

*/
 
 31 #define __UID_T_TYPE        __U32_TYPE
 32 #define __GID_T_TYPE        __U32_TYPE
 39 #define __PID_T_TYPE        __S32_TYPE
 53 #define __DADDR_T_TYPE      __S32_TYPE

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

我們以__key_t為例子來尋定義的蛛絲馬跡:


1.__STD_TYPE   __KEY_T_TYPE   __key_t            //bits/types.h

2.#define  __KEY_T_TYPE   __S32_TYPE              //bits/typesizes.h

3.#define  __S32_TYPE  int

從3-2-1就是我們的: typedef int   __key_t ;

至於我們看到的ipc中的key_t資料型別,則又是在__key_t基礎上定義的,我們可以在ipc.h中找到這個定義:

 47 #ifndef __key_t_defined
 48 typedef __key_t key_t;
 49 # define __key_t_defined
 50 #endif

所以,我們在linux c 程式設計裡面經常看到的那些莫名奇妙的資料型別,基本都可以通過以上方式找到最終的基本資料型別。

相關推薦

glibc資料型別定義分析

  本文主要涉及到的庫檔案位於/usr/include/bits目錄下,檔案包括wordsize.h,types.h,typesizes.h 等檔案。   wordsize.h中主要定義了當前機器的字大小。內容如下:   ...   #define __WORDSIZE  3

四、資料庫資料型別

  首先補充點了解的小知識; select * from mysql.user #顯示出來亂了 select * from mysql.user\G #加了\G後一行一行顯示了 一、資料型別:分不同種類去存不同型別的資料 儲存引

c++筆記資料型別轉換

#include <iostream> #include <string> using namespace std; class Complex { public: Complex() //預設建構函式 { real = 0; imag = 0;

Python基本語法資料型別

  Python資料型別 基本資料型別 資料型別 說明 Numbers int 有符號整型 long 長整型[也可以代表八

《SQL入門經典》筆記(第二章:建立資料庫資料型別

“建立資料庫”包括五個內容:定義資料結構、管理資料庫物件、規格化過程、操作資料以及管理資料庫事務   1. 什麼是資料型別? 資料型別用於指定特定列所包含資料的規則,它決定了資料儲存在列裡的方式。SQL最基本的資料型別有字串、數值、日期和時間(其實每個實現都有自己的資料型別

JavaSE資料型別與運算子

package cn.shuju.java; import java.io.IOException; //本節目標 //1.java識別符號與關鍵字 //2.java資料型別劃分 //3.java運算子 //對於類和變數的命名,java的標準命名規範為“駝峰”命名法 //對於類名,類

《JavaScript高階程式設計》——JS基本概念資料型別

ECMAScript 中有五種簡單資料型別(基本資料型別):Undefined、Null、Boolean、Number 和 String。還有一種複雜資料模型:Object。 資料型別 1 typeof 操作符 typeof 用來檢測給定變數的資料型別。對一個值使用 typeof

資料庫資料型別

首先補充點了解的小知識; select * from mysql.user #顯示出來亂了 select * from mysql.user\G #加了\G後一行一行顯示了 一、資料型別:分不同種類去存不同型別的資料 儲存引擎決定了表的型別,而表記憶體放的資料也要有不同的型別,每種資料型別

(六)Hive SQL資料型別和儲存格式

(六)Hive SQL之資料型別和儲存格式   目錄 一、資料型別 1、基本資料型別 2、複雜型別 二、儲存格式 (1)textfile  (2)SequenceFile 

mysql資料型別和select語句(group by、 limit)

mysql之資料型別的理解 mysql資料型別之整形 mysql資料型別之浮點型 mysql資料型別之日期時間型 mysql資料型別之字元型 刪除記錄(單表刪除) delete from 表單 where id=5 select

Mysql效能優化資料型別優化

一、選擇正確的資料型別對於獲得高效能至關重要 1.1更小的通常更好 佔用更少的磁碟、記憶體和CPU快取 1.2儘量避免null 如果查詢中包含可為null的列,對Mysql來說更難優化,因為可為null的列使得索引、索引統計和值都更復雜。會使用更多的儲存空間. 2、整數和實數

java複習筆記資料型別

在java中一共有8種基本型 4種整型:int儲存4位元組、short儲存2位元組、long儲存8位元組、byte儲存1位元組; 2種浮點型:float儲存4位元組、double儲存8位元組; char型別:在程式中少用此種類型,多用String字串作為抽象資料型別,這樣可以減少一些不必

Hive-5-Hive SQL資料型別和儲存格式

原文地址:https://www.cnblogs.com/qingyunzong/p/8733924.html 一、資料型別 1.1、基本資料型別 Hive 支援關係型資料中大多數基本資料型別,和其他的SQL語言一樣,這些都是保留字。需要注意的是所有的這些資料型別都是對Java中介面的實

C#資料型別轉換,迴圈和三元表示式使用方法

轉換資料型別 Convert.To…… 想把資料轉換成什麼型別就寫些什麼樣的,在convert.To直接加 //這一行程式碼要用int型別的變數來接收,那麼可以說,這個方法的返回值是int型別 Int numbers=convert.ToInt32(“4”);  

python開發基礎資料型別、字元編碼、檔案操作

一、知識點 1.身份運算: 2.現在計算機系統通用的字元編碼工作方式:在計算機記憶體中,統一使用Unicode編碼,當需要儲存到硬碟或者需要傳輸的時候,就轉換為UTF-8編碼。用記事本編輯的時候,從檔案讀取的UTF-8字元被轉換為Unicode字元到記憶體裡,編輯完成後,儲存的時候再把Unicode轉

Python學習手冊資料型別

 在上一篇文章中,我們介紹了 Python 的異常和檔案,現在我們介紹 Python 中的資料型別。 檢視上一篇文章請點選:https://www.cnblogs.com/dustman/p/9979931.html 資料型別None 型別None 型別是 Python 的特殊型別,它

MySQL基礎系列 資料型別大全

MySQL中定義資料欄位的型別對你資料庫的優化是非常重要的。MySQL支援多種型別,大致可以分為三類:數值、日期/時間和字串(字元)型別。 數值型別 MySQL支援所有標準SQL數值資料型別。 這些型別包括嚴格數值資料型別(INTEGER、SMALLINT、DECIMAL和NUMERIC

JavaScript高階程式設計第三版學習筆記(一)資料型別區分詳談

  null、NaN、undefined三者的區別是什麼?   在初次接觸到JavaScript的時候,傻傻的分不清null、NaN、undefined三者到底區別何在,在實際的專案開發中也因為這個問題而困惑久矣。針對這個問題,我特意查找了多方資料,在筆記本上做了詳細的分析記錄,但是由於紙質資料不便於攜帶、

前端入門8-JavaScript語法資料型別和變數

宣告 本系列文章內容全部梳理自以下幾個來源: 《JavaScript權威指南》 MDN web docs Github:smyhvae/web Github:goddyZhao/Translation/JavaScript 作為一個前端小白,入門跟著這幾個來源學習,感謝作者的分享,

Hive資料型別

  基礎資料型別與java資料型別一致 整型 TINYINT — 微整型,只佔用1個位元組,只能儲存0-255的整數。 SMALLINT– 小整型,佔用2個位元組,儲存範圍–32768 到 32767。 INT– 整型,佔用4個位元組,儲存範圍-2147483648到214748364