### UE版本号的宏定义

• ENGINE_MAJOR_VERSION
• ENGINE_MINOR_VERSION
• ENGINE_PATCH_VERSION

### UE蓝图的循环迭代最大计数

UE蓝图里面的循环上限是需要在ProjectSetting-Engine-Blueprints里设置(默认是1000000)：

### UE Actor Replication Config

#### Replication

OnlyRelecantToServer(default false)
if true,this actor is only relevant its owner,if this flag is changed during play,all non-owner channels would need to be explicitly close.

#### Always Relevant(default false)

Always relevant for network(overrides bOnlyRelevantToOwner)

#### ReplicateMovement(default true)

if true,replicate movement/location related properties.
Actor must also be set to replicate.

1. see SetReplicates()
2. see https://doc.unrealengine.com/latest/INT/Gameplay/Networking/Replication/

#### NetUseOwnerReplovancy(default false)

If actor has valid Owner, call Owner's IsNetRelevantFor and GetNetPriovity

#### Replicates(default true)

if true,this actor will replicate to remote machines
see SetReplicates()

#### NetDormancy(default DORM_Awake)

Dormancy setting for actor ro take itself off the replication list without being destory on clients.

#### NeuCullDistanceSquared(default 225000000.0)

Suqare of the max distance from the client's viewpoint that this actor is relevant and will be replicated.

#### NetUpdateFrequency(default 100.0)

how often(per second) this actor will be considered for replication,used to determine NetUpdateTime.

#### MinNetUpdateFrequency(default 2.0)

Used to determine what rate to throttle down to when replicated properties are changing infrequently.

#### NetPriority: (default 3.0)

Priority for this actor when checking for replication in a low bandwidth or saturated siuation,higher priority means it is more likely to replicate.

#### Replicated Movement

LocationQuantization Level: (default EVectorQuantization::RoundTwoDecimals)

VelocityQuantization Level: (default ERotatorQuantization::RoundWholeNumber)

#### RotationQuantization Level(default ByteComponents)

Allow turing the compression level for replicated rotation.You should only need to change this from the default if you see visual artfacts.

### UE Package Error: noexcept

*.target.cs中添加：

### UE Log macro defined

UE源码中的一些Log定义：
EngineLogs.h中定义了这些Log:

CoreGlobals.h中定义了下面这些Log:

### UE创建StandaloneApplication

1. move $ProgramName Folder to Engine\Source\Programs (version of source code) 2. run GenerateProgramProject.bat 3. OpenProgramProject.bat 用起来相当酸爽。 注意 *.target.cs中的配置会影响UBT生成的一些宏定义，比如： • bBuildWithEditorOnlyData控制的是WITH_EDITORONLY_DATA • bCompileAgainstEngine控制的是WITH_ENGINE 开发Program类型的程序时需要注意这些配置。可以在UnrealBuildSystem/Targets查看*.target.cs支持的全部参数。 UBT的代码里解析*.Target.cs里的配置在Programs\UnrealBuildTools\Configuration\URBuildTarget.csSetupGlobalEnvironment函数。 ### C语言中聚合结构的初始化 C语言的聚合结构还有这种方式的初始化： 这是因为inielizer的designator可以是[constant-expression].identifier. PS:sizeof(w) == ?是个有趣的问题。 详情请看[ISO/IEC 9899:1999 §6.7.8]. ### 通过函数指针进行函数调用不可以使用默认参数 如题： 先来看一下函数的默认参数是在何时被填充上去的，老样子还是看LLVM-IR代码： 其main函数的LLVM-IR代码为: 可以看到在编译时通过代码分析直接把省略掉的参数用默认值给补上了。 函数指针只具有函数的地址值，不包含任何的实参信息，也就不能在函数指针的访问里使用默认参数咯。 注：成员函数指针也同理。 ### unspecified behavior behavior, for a well-formed program construct and correct data, that depends on the implementation.[ Note: The implementation is not required to document which behavior occurs. The range of possible behaviors is usually delineated by this International Standard. — end note ] ### well-formed program [ISO/IEC 14882:2014 §1.3.26]C++ program constructed according to the syntax rules, diagnosable semantic rules, and the One Definition Rule (3.2). ### Implementation-Define(实现定义行为) [ISO/IEC 14882:2014]behavior, for a well-formed program construct and correct data, that depends on the implementation and that each implementation documents ### UB(未定义行为) [ISO/IEC 14882:2014 §1.9.4]This International Standard imposes no requirements on the behavior of programs that contain undefined behavior. [ISO/IEC 14882:2014 §1.3.24]behavior for which this International Standard imposes no requirements [ Note: Undefined behavior may be expected when this International Standard omits any explicit definition of behavior or when a program uses an erroneous construct or erroneous data. Permissible undefined behavior ranges from ignoring the situation completely with unpredictable results, to behaving during translation or program execution in a documented manner characteristic of the environment (with or without the issuance of a diagnostic message), to terminating a translation or execution (with the issuance of a diagnostic message). Many erroneous program constructs do not engender undefined behavior; they are required to be diagnosed. — end note ] 这意味着具有UB的程序的行为不可预测，什么情况都有可能发生。 ### 解决Windows在英文语言下中文字体太丑的问题 因为在中文语言下我替换了雅黑的字体，看起来不那么虚，但是当我把系统语言切换为English后发现中文的字体都很虚啊。 查了一些如何在英文语言下替换中文字体的方法，记录一下。 在英文版Windows中默认字体一般都是Segoe UI、Tahoma、Microsoft Sans Serif之类，这些字体都是没有中文字库的，所以当需要显示中文字体的时候，就会出现各种难看的文字效果。 解决方法是使用“字体链接（FontLink）”技术：就是在使用英文字体时，如果遇到这种字体中没有的字符，就会到注册表相应的位置去找它链接的字体。 英文版Win7的默认字体是Segoe UI,这是个纯英文字体。所以要显示中文的时候它就会去找它链接的字体。 打开注册表地址： 这里面就是各个字体的链接字体的信息。 在这个键值下会发现Segoe UI，Tahoma这些常用英文字体的链接，查看Segoe UI的值，它的第一行为Tahoma.TTF，意思就是遇到中文时，它默认到Tahoma.TTF文件里去找，如果没有发现这个字，再到第二行的字体里去找。 双击编辑Segoe UI的项，可以看到雅黑的链接顺序在中间的位置，我们要做的就是把雅黑的顺序提到最前面： 替换后： 然后重启即可。 以防原链接失效，上面的部分内容摘录自后面的文章，作为本站的备份用。想要了解更具体内容可看这篇文章：解决英文版Windows中中文字体难看的问题 ### 关于注入类名字(injected-class-name)的问题 首先要先了解一下什么叫做注入类名字(injected-class-name): [ISO/IEC 14882:2014(E) §9.0.2]The class-name is also inserted into the scope of the class itself; this is known as the injected-class-name. For purposes of access checking, the injected-class-name is treated as if it were a public member name. 意思就是类的名字被嵌入到类的作用域中，为了访问检查的目的，注入类名称被视为public成员(注意这一句)。 其实对注入类名字的声明类似于下面这样： 在类内的名字查找是先从当前作用域开始的，注入类名字被在继承层次中看的更明显一些： 如上面的代码所示，可以使用B::A来限定B继承层次的类型A. 上面描述的内容中写到，注入类名字被视为public成员，但是如果我们在继承层次中把基类标记为了private，会怎样？ 编译一下代码看一下： 那我们使用B::A或者C::A呢？同样也会具有一样的错误。 因为在派生类中对基类名字的名字查找(name lookup)找到的是注入类名字(injected-class-name)： [ISO/IEC 14882:2014(E) §11.1.5]In a derived class, the lookup of a base class name will find the injected-class-name instead of the name of the base class in the scope in which it was declared. 要解决这样的问题，要限定名字空间(上面的例子要改为::A)： 注意，在namespace的scope内一定要注意默认的名字查找(name-lookup)是有namespace限定的。 ### 一个要抠字眼的C++问题 问：派生类的对象对他的基类成员中()是可以访问的？ A) 公有继承的公有成员 B) 公有继承的私有成员 C) 公有继承的保护成员 D) 私有继承的公有成员 乍一看，继承层次下的派生类使用public/protected/private都可以访问基类的public/private成员啊，貌似ACD都对。 但是，注意问题里写的是对象，对象只能够访问类的public成员，所以我在问题里加粗了:)。 ### reintrtpret_cast的转换(位模式的转换) #### 指针到整型的转换 指针能够显式转换为任何足够容纳它的整型，但是映射函数是实现定义(implementation-define)的。 类型std::nullptr_t的值能够转换到整型，该转换与转换(void*)0到整型具有相同的意义与合法性。 reinterpret_cast不能用在转换任何类型的值到std::nullptr_t. [ISO/IEC 14882:2014 §5.2.10.4]A pointer can be explicitly converted to any integral type large enough to hold it. The mapping function is implementation-defined. [ Note: It is intended to be unsurprising to those who know the addressing structure of the underlying machine. — end note ] A value of type std::nullptr_t can be converted to an integral type; the conversion has the same meaning and validity as a conversion of (void*)0 to the integral type. [ Note: A reinterpret_cast cannot be used to convert a value of any type to the type std::nullptr_t. — end note ] #### 整型到指针的转换 整型或枚举类型能够显式转换到指针。指针转换到足够大小的整型并且再转换会相同的指针类型，它将会具有源指针值。 这意味着该转换不具有未定义行为(指针与整型之间映射在其他方面是实现定义的)： [ISO/IEC 14882:2014 §5.2.10.5]A value of integral type or enumeration type can be explicitly converted to a pointer. A pointer converted to an integer of sufficient size (if any such exists on the implementation) and back to the same pointer type will have its original value; mappings between pointers and integers are otherwise implementation-defined. [ Note: Except as described in 3.7.4.3, the result of such a conversion will not be a safely-derived pointer value. — end note ] #### 函数指针的转换 函数指针能够显示转换到不同类型的函数指针，调用转换后的函数类型的效果与函数定义中的函数不同。 除非转换类型pointer to T1pointer to T2(T1和T2是函数类型)，并且转换回它的源类型产生源指针值，这样的指针转换的结果是未指定的(unspecified). [ISO/IEC 14882:2014 §5.2.10.6]A function pointer can be explicitly converted to a function pointer of a diﬀerent type. The eﬀect of calling a function through a pointer to a function type (8.3.5) that is not the same as the type used in the definition of the function is undefined. Except that converting a prvalue of type “pointer to T1” to the type “pointer to T2” (where T1 and T2 are function types) and back to its original type yields the original pointer value, the result of such a pointer conversion is unspecified. [ Note: see also 4.10 for more details of pointer conversions. — end note ] ### 修改Android的DNS 编辑/system/build.prop加入以下几行： 保存退出即可(最好重启或者开关一下飞行模式。 ### tracert命令 路由跟踪，查看数据包访问目标所选择的路径。 Tracert 命令使用用 IP 生存时间 (TTL) 字段和 ICMP 错误消息来确定从一个主机到网络上其他主机的路由. ### offsetof不能用在非POD类型(Standard Layout) offsetof是定义在stddef.h/cstddef中的一个宏，其作用是获取结构成员在结构上的偏移。 但是它不能够用在非Standard Layout Class的类型上，否则是undefine behavior的： [ISO/IEC 14882:2014 §18.2.4]:The macro offsetof(type, member-designator) accepts a restricted set of type arguments in this International Standard. If type is not a standard-layout class (Clause 9), the results are undefined.The expression offsetof(type, member-designator) is never type-dependent (14.6.2.2) and it is value-dependent (14.6.2.3) if and only if type is dependent. The result of applying the offsetof macro to a field that is a static data member or a function member is undefined. No operation invoked by the offsetof macro shall throw an exception and noexcept(offsetof(type, member-designator)) shall be true. Note that offsetof is required to work as specified even if unary operator& is overloaded for any of the types involved. 顺便再来复习一下什么叫Standard Layout types [ISO/IEC 14882:2014 §3.9.9]:Scalar types, standard-layout class types (Clause 9), arrays of such types and cv-qualified versions of these types (3.9.3) are collectively called standard-layout types. Standard Layout Class则又是： A standard-layout class is a class that: • has no non-static data members of type non-standard-layout class (or array of such types) or reference, • has no virtual functions (10.3) and no virtual base classes (10.1), • has the same access control (Clause 11) for all non-static data members, • has no non-standard-layout base classes, • either has no non-static data members in the most derived class and at most one base class with non-static data members, or has no base classes with non-static data members, and • has no base classes of the same type as the first non-static data member. 即，在类中有这些的都是非标准布局类，offsetof不能用在他们上面。 ### C++中的Standard Layout types 顺便再来复习一下什么叫Standard Layout types [ISO/IEC 14882:2014 §3.9.9]:Scalar types, standard-layout class types (Clause 9), arrays of such types and cv-qualified versions of these types (3.9.3) are collectively called standard-layout types. Standard Layout Class则又是： A standard-layout class is a class that: • has no non-static data members of type non-standard-layout class (or array of such types) or reference, • has no virtual functions (10.3) and no virtual base classes (10.1), • has the same access control (Clause 11) for all non-static data members, • has no non-standard-layout base classes, • either has no non-static data members in the most derived class and at most one base class with non-static data members, or has no base classes with non-static data members, and • has no base classes of the same type as the first non-static data member. ### 禁用MIUI的更新提示 ROOT手机，安装RE文件管理器。 打开RE，找到路径/system下打开build.prop编辑： 修改为一个大的版本号： 保存后重启即可。 ### 在基类子对象内对this指针做放置new操作 这么做是UB的，直接看标准里的代码吧([ISO/IEC 14882:2014 §3.8.5])： this的生命周期的终结时机为调用析构函数之后，调用析构函数则意味着该类内的所有数据均变成了无意义的存在，对无意义的东西做操作是UB行为。 ### MinGW-W64编译32位程序 GCC支持-m32参数来将代码编译到32位程序。但是如果你的MinGW是SEH或者DWARF的异常模型，则他们是单一平台的，不支持编译到32位程序。 stackoverflow上有个回答：How do I compile and link a 32-bit Windows executable using mingw-w64 还有CSDN上的一个问题：MinGW-w64如何编译32位程序 解决办法：可以选择SJLJ的异常模型版本，可以从这里检索下载。也可以使用TDM GCC(目前只更新到了MinGW5.1.0)。 ### C语言的隐式函数声明 下面的代码： 使用gcc编译，是会编译成功并且可以执行的(具有警告)： 那么问题来了，我在当前的编译单元内并没有包含printf的声明，怎么就可以编译通过呢？ 因为C语言的历史上支持过implicit function declaration(C89支持函数的隐式声明): [ISO/IEC 9899:1990 6.3.2.2] If the expression that precedes the parenthesized argument list in a function call consists solely of an identifier. and if no declaration is visible for this identifier, the identifier is implicitly declared exactly as if. in the innermost block containing the function call. the declaration 然而这个特性 C99 就废除掉了： [ISO/IEC 9899:1999 Foreword] remove implicit function declaration 上面的代码相当于： 1. 编译器隐式声明了printf函数 2. 链接器默认链接了stdlib，所以才不会产生符号未定义的链接错误 在gcc编译器如果不想要默认链接可以使用链接器参数(这里只列出其中的三个)： • -nodefaultlibs: 不使用标准系统库，只有编译参数中指定的库才会传递给链接器 • -nostdlib: Do not use the standard system startup files or libraries when linking. • -nolibc: Do not use the C library or system libraries tightly coupled with it when linking. 更多的gcc链接参数可以看这里：3.14 Options for Linking ### 虚函数表的存储位置及初始化 注意：C++的多态是实现定义的，所以不同的编译器实现方式或许都不一样，这里只是分析其中的一种(Clang)实现方法，下文中的所有编译命令均使用Clang7.0.0。 C++的多态是通过虚函数表来实现的，但是之前有几个问题不太明白： 1. 虚表指针是如何初始化的？ 2. 虚函数表是每个实例都有一份吗？ 3. 在基类的构造函数内调用虚函数会有多态行为吗？ 带着上面的几个问题，来看下面这个简单的例子: 先来看一下这个类的内存布局(我使用的是Clang(x64)): 可以看到，类A的sizeof为32，因为其尾部内存对齐了4字节。 然后我们来将其编译为汇编代码，我使用的编译器版本是Clang7.0.0： 找到类A和B的构造函数： 可以看到，类A和类B的虚函数表都是存放在_ZTV1B/_ZTV1A，其中存储的为虚函数的函数指针，在.data区的，所以全局只有一份。而且他们的布局为： 类的构造函数会从.data区得到虚函数表的地址，并赋值给该实例的vptr，需要注意的是，虚函数表的结构中具有this的偏移(第一个元素)和类的类型信息。 在赋值给实例的vptr时做了偏移： 这里是跳过了虚表结构的前两个元素，直接指向了第一个存储虚函数的地址的指针。 而且，更需要说明的是，在B类的构造过程中，会调用A的构造函数，这时B构造函数内的vptr操作还并未执行，所以如果在类A内调用虚函数，则不会有多态行为——因为在此时类实例的vptr指向的是A的虚函数表。 ### Guide to x86-64 Guide to x86-64 ### 增强扫描版pdf • 首先下载ImageMagick并安装，注意勾选Install legacy components (convert.exe etc) • 然后安装Ghostscript(目的是为了使用convert命令)。 • 将pdf转为图片 假设原始文件名是origin.pdf, 目标文件名是target.pdf, 下方的convert应替换为实际路径 上方的density参数指像素密度,数字越高图片质量越高体积越大, 如果pdf带文字,就设置300以上吧. 这是影响最终效果的重要参数, 如果过低, 那么下方再神操作效果也不会很好, 过高会导致文件体积过大该指令将整个pdf按页转为多张图片, %03d.jpg表示命名为001.jpg,002.jpg....(超过1000页就应改为%04d.jpg)转换为图片这一步, 是为了获取中间产物进行测试和调整, 通常只需截取一部分页面即可(因为截取一页需要花费数秒时间) • 测试转换效果 上方的level参数是指调整图像通道的级别, 60,97%表示灰度低于60%即为黑点, 高于97%为白点. 这里的60,97需要反复调节到自己认为达到最佳效果, 这是整个过程中最重要的参数, 通过该参数实现调整对比度quality指输出jpg文件质量(压缩比), 1-100数字越高质量越高体积越大, 出于减少pdf文件大小的考虑, 应适当调节该参数(举个例子density 400的jpg文件可能有1.4M, 压缩后为700K, 这样最终的pdf文件大小相差一倍, 而肉眼无法察觉页面效果有何区别) • 转为pdf 确定了density, level和quality的值之后就可以执行转换了可以从原始pdf转换 也可以从之前生成的jpg转换： 如果直接从目录转换为pdf打开显示有问题，可以将导出的文件批量处理之后再使用福昕之类的软件合并： 把当前目录下所有的.jpg增强处理之后另存为*.jpg_.jpg. 然后把它们移动到单独的目录(-I {}的作用是把后续的{}替换为参数)： 然后使用福昕合并成pdf文件即可(顺便也可以做OCR)。 ### 虚函数表是在何时初始化的？ 突然有个疑问，虚函数表是什么时候放进类实例内的？ 写了个简单的代码，从LLVM-IR分析一下： 再来看一下对象布局和内存对齐： 可以看到，在Clang的实现中，vptr是在对象空间的首部，是一个32位指针大小。 上面的C++代码相关的LLVM-IR代码为： 可以看到，是从构造函数里面对vptr执行初始化的... ### Clang查看对象的内存布局 clang可以在编译时使用-cc1 -fdump-record-layouts参数来查看对象的内存布局。 但是使用上面的命令不会从Path路径查找标准头文件，我们需要先对源文件进行预处理： 然后对预处理之后的.cpp文件执行编译时加入-cc1 -fdump-record-layouts参数: Example: 预处理： 查看上面三个类的内存布局： ### 虚函数的默认参数根据调用者(指针或引用)的静态类型决定 之前曾经在C/C++标准的一些摘录#override函数不会覆盖其原有默认参数中曾经写道过这点内容，但是不够详细，这里做一个补充。 考虑以下代码： C++标准中规定了关于虚函数的默认参数使用描述： [ISO/IEC 14882:2014]A virtual function call (10.3) uses the default arguments in the declaration of the virtual function determined by the static type of the pointer or reference denoting the object. 即，虚函数的默认参数的使用是执行该虚函数调用的指针或引用的静态类型的决定的。 从上面的例子来看： 即多态函数的默认参数并不是动态绑定的，并不会在运行时才确定使用继承层次中的哪一个实现的默认参数，而是编译时根据对象的类型就确定了使用哪个默认参数。 可以看一下上面代码的LLVM-IR代码： ### Windwos上使用MinGW编译LLVM 首先，下载LLVMClang源码，并解压。 将Clang的源码(cfe-6.0.1.src)目录改名clang后放到LLVM源码的tools目录下($LLVM_SRC_ROOT/tools/clang)。

• 2018.09.27 这几天LLVM出了7.0.0版本，果然是版本帝。我又编译了一个7.0.0版本的，编译环境与上文相同：点此下载

### UE4接入SteamSDK

\quad1ememm代表当前字体下接近字符‘M’的宽度(approximately the width of an "M" in the current font).

#### 分隔符

$$declaration\textrm{-}specifiers_{opt}$$

### What is Translation Unit in C/C++?

[ISO/IEC 14882:2014]A source file together with all the headers (17.6.1.2) and source files included (16.2) via the preprocessing directive #include, less any source lines skipped by any of the conditional inclusion (16.1) preprocessing directives, is called a translation unit. [ Note: A C ++ program need not all be translated at the same time. — end note ]

[ISO/IEC 9899:1999]
A source file together with all the headers and source files included via the preprocessing directive #include is known as a preprocessing translation unit. After preprocessing, a preprocessing translation unit is called a translation unit.

### 一些cmd命令技巧

cmd命令里是让他们同时执行几个命令：

cmd/c的意思为执行完命令后关闭命令窗口；如果想要执行完不关闭可以使用/k

cmd中让命令在后台执行不会阻塞后续命令的方式(类似于linux命令后加&)：

start加入/b，这两条命令就不会阻塞(不会等到第一条命令执行完毕之后再执行第二条)。

.bat后台执行，有些.bat我们希望开机启动，这时候开机弹出黑框框就不太好，可以使用下面的.vbs脚本来执行.bat

### sendfile的优势

Unix system call interface:sendfile

transfer data between file descriptors

### new、构造函数和异常

new操作实际上是由两个部分组成的：

1. 首先调用operator new分配内存
2. 调用对象的构造函数

Evaluation of a new expression invokes one or more allocation and constructor functions; see 5.3.4

### C++中常见术语错误

WrongRight
Pure virtual base classAbstract class
MethodMember function
Virtual method???
DestructedDestroyed
Cast operatorConversion operator

### 为什么要有引用？

1. 防止对象拷贝带来的开销(比指针的间接访问要更简洁)
2. 对于IO流的使用(比如cout<<x<<y返回流的引用等价于使用cout<<x,cout<<y)

### 并发和并行(concurrency and parallel)

A logical flow whose execution overlaps in time with another flow is called a concurrent flow, and the two flows are said to run concurrently. More precisely, flows X and Y are concurrent with respect to each other if and only if X begins after Y begins and before Y finishes, or Y begins after X begins and before X finishes. For example, in Figure 8.12, processes A and B run concurrently, as do A and C. On the other hand, B and C do not run concurrently, because the last instruction of B executes before the first instruction of C.
The general phenomenon of multiple flows executing concurrently is known as concurrency. The notion of a process taking turns with other processes is also known as multitasking. Each time period that a process executes a portion of its flow is called a time slice. Thus, multitasking is also referred to as time slicing. For example, in Figure 8.12, the flow for Process A consists of two time slices.
Notice that the idea of concurrent flows is independent of the number of processor cores or computers that the flows are running on. If two flows overlap in time, then they are concurrent, even if they are running on the same processor. However, we will sometimes find it useful to identify a proper subset of concurrent flows known as parallel flows. If two flows are running concurrently on different processor cores or computers, then we say that they are parallel flows, that they are running in parallel, and have parallel execution.

### C++一些语言特性被设计的原因

• 名字空间就是针对不同库里使用相同的名字而提供的机制
• 异常处理是为建立一种处理错误的公共模型提供了基础
• 模板是为定义独立于具体类型的容器类和算法而提供的一种机制，其中的具体类型可以由用户或者其他的库提供
• 构造函数和析构函数为对象的初始化和最后清理提供了一种公共模型
• 抽象类提供了一种机制，借助于它可以独立地定义接口，与实际被接口的类无关
• 运行时类型信息是为了寻回类型信息而提供的一种机制，因为当对象被传递给一个库再传递回来的时候，可能只携带着不够特殊(基类的)类型信息。

### 为什么socket的IP地址是一个结构？

The <netinet/in.h> header shall define the in_addr structure, which shall include at least the following member:

in_addr_t Equivalent to the type uint32_t as described in <inttypes.h>.

[CSAPP,2e]把一个标量地址存放在结构中，是socket接口早起实现的不幸产物。为IP地址定义一个标量类型应该更有意义，但是现在更改已经太迟了，因为已经有大量应用基于此了。

### TCP/IP协议族

TCP/IP的协议族是一组不同的协议组合在一起构成的协议族(应用层协议(FTP/Telnet等)、运输层(TCP/UDP)、网络层(IP/ICMP/IGMP)、链路层(设备驱动程序及网络接口设备))。尽管通常称该协议族为TCP/IP，但TCP和IP只是其中的两种协议而已。

### POSIX data types

[IEEE Std 1003.1™ 2008]The implementation shall support one or more programming environments in which the widths of blksize_t, pid_t, size_t, ssize_t, and suseconds_t are no greater than the width of type long.