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