Quellcode durchsuchen

feat: 添加编译链接规则

nicetry12138 vor 1 Jahr
Ursprung
Commit
959e1f3f45

+ 3 - 0
.gitignore

@@ -0,0 +1,3 @@
+Debug
+x64
+.vs

+ 0 - 0
重学CPP/README.md


BIN
重学CPP/编译器/Image/001.png


BIN
重学CPP/编译器/Image/002.png


BIN
重学CPP/编译器/Image/003.png


BIN
重学CPP/编译器/Image/004.png


+ 133 - 0
重学CPP/编译器/RAEDME.md

@@ -0,0 +1,133 @@
+# 编译器
+
+## 转换单元
+
+写好的每一个源文件(.cpp .c) 将其包含的头文件 (`#incluide <xxx.h>`) 合并后,称为一个**转换单元**
+
+编译器单独的将每一个**转化单元**生成为对应的**对象文件**(.obj),对象文件包含了转换单元的**机器码**和转换单元的**引用信息**(不在转换单元中定义的对象)
+
+最后链接器将各个转换单元的对象文件链接起来,生成**目标程序**
+
+> 比如在对象文件 A 中包含了定义在其他转换单元的引用,那么就去其他转化单元的对象文件中寻找,这个引用的定义来建立链接,如果在在所有的对象文件中都找不到这个定义,那么就会生成一个链接错误
+
+![](Image/001.png)
+
+
+如上图所示,在尝试使用 `testX()` 函数时,由于无法找到对应函数而爆出链接错误,并且报错的文件也是 `obj` 后缀结尾的文件
+
+![](Image/002.png)
+
+相对而言,上图所示的错误则是在解析**转化单元**就报错了,所以文件后缀为 `cpp`
+
+## 未定义行为
+
+在编写代码中 C++ 标准未作规定的行为,称为未定义行为,未定义行为的结果是不确定的,具体在不同的编译器下会有不同的效果,比如
+
+```cpp
+c = 2 * a ++ + ++a * 6;
+```
+
+这里先算 a++ 还是先算 ++a 就是一个未定义行为
+
+![](Image/003.png)
+
+```cpp
+int x = -25602;
+x = x >> 2;
+```
+
+x 的结果在不同的编译器下是不确定的,所以这也属于未定义行为。通常情况下,对于负数的右移操作,大多数编译器会执行算术右移(arithmetic right shift),在这种情况下,符号位会被复制到右移后空出的位置,以保持数值的符号不变。但是,这并不是由 C++ 语言标准强制规定的,所以理论上编译器可以选择不同的实现方式
+
+所以一般对数据进行位运算都是使用**无符号**
+
+## One Definitaion Rule
+
+ODR 是一系列规则,而不是一个规则,程序中定义的每个对象都对应着自己的规则
+
+但是基本上来讲任何的变量、函数、类、枚举、模板、在每个转换单元中都只允许有一个定义;非 inline 的函数或变量,在整个程序中有且仅有一个**定义**
+
+![](Image/004.png)
+
+如上图,对 `Test` 重复声明多次并不会报错,因为只定义了一次   
+
+即使非 inline 的函数或变量定义在不同的文件中,在**链接阶段**仍然会报错
+
+> 被 `const` 或者 `static` 定义的函数或者属性只会在当前转换单元内生效,所以可以定义相同的名称
+
+```cpp
+inline int a = 10; // 内联变量 C++ 17 之后支持该写法
+```
+
+## 名称的链接属性
+
+程序中的变量、凹函数、结构等都有着自己的名字,这些名字具有不同的链接属性,链接器就是根据这些链接属性来把各个对象链接起来的
+
+链接属性分为以下三种
+
+1. 内部链接属性:该名称仅仅在本转化单元中有效
+2. 外部链接属性:该名称在其他的转换单元中也有效
+3. 无链接属性:该名称仅仅能够在用于该名称的作用域内访问
+
+```cpp
+#include <iostream>
+
+static int x = 10;
+
+extern int a = 1;
+
+inline int ii = 10;
+
+int pp = 20;
+
+int main() {
+    int a = 0;
+    return 0;
+}
+```
+
+对于上面的代码
+
+- `static int x` 定义在全局区,由于 `static`,属于内部链接属性
+- `extern static int a` 定义在全局区, 由于 `extern`,属于外部链接属性
+- `int pp = 20` 定义在全局区,属于外部链接属性
+- `inline int ii = 10` 定义在全局区,属于外部链接属性
+- `int a = 0` 属于无链接属性
+
+对于内联属性的作用,在两个文件中分别定义同名的内联属性,并不会报错,但是两个属性只有一个有效,无效的属性的值会被有效的属性的值覆盖掉
+
+```cpp
+// T.cpp
+#include <iostream>
+
+inline int ii = 40;
+
+void PPInline_t() {
+	std::cout << ii << std::endl;
+}
+
+
+// Demo.cpp
+#include <iostream>
+
+void PPInline_t();
+
+inline int ii = 20;
+
+void PPInline() {
+    std::cout << ii << std::endl;
+}
+
+
+int main()
+{
+
+    PPInline_t();   // 输出 20
+    PPInline();     // 输出 20
+    return 0;
+}
+```
+
+通过上述代码,可以知道 Demo.cpp 中定义 ii 把 T.cpp 中定义的 ii 覆盖掉了。当一个变量被声明为 `inline` 时,即使它在多个源文件中包含,链接器也会将它们视为同一个对象。虽然 inline 变量提供了一种方便的方式来避免多重定义的问题,但在实践中使用时,最好确保 inline 变量在整个程序中只有一个定义点,以避免潜在的不确定性。
+
+
+

+ 31 - 0
重学CPP/编译器/src/Demo/Demo.sln

@@ -0,0 +1,31 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 17
+VisualStudioVersion = 17.9.34723.18
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Demo", "Demo\Demo.vcxproj", "{65893CD7-7B83-4264-952B-47E4EF421F54}"
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|x64 = Debug|x64
+		Debug|x86 = Debug|x86
+		Release|x64 = Release|x64
+		Release|x86 = Release|x86
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{65893CD7-7B83-4264-952B-47E4EF421F54}.Debug|x64.ActiveCfg = Debug|x64
+		{65893CD7-7B83-4264-952B-47E4EF421F54}.Debug|x64.Build.0 = Debug|x64
+		{65893CD7-7B83-4264-952B-47E4EF421F54}.Debug|x86.ActiveCfg = Debug|Win32
+		{65893CD7-7B83-4264-952B-47E4EF421F54}.Debug|x86.Build.0 = Debug|Win32
+		{65893CD7-7B83-4264-952B-47E4EF421F54}.Release|x64.ActiveCfg = Release|x64
+		{65893CD7-7B83-4264-952B-47E4EF421F54}.Release|x64.Build.0 = Release|x64
+		{65893CD7-7B83-4264-952B-47E4EF421F54}.Release|x86.ActiveCfg = Release|Win32
+		{65893CD7-7B83-4264-952B-47E4EF421F54}.Release|x86.Build.0 = Release|Win32
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+	GlobalSection(ExtensibilityGlobals) = postSolution
+		SolutionGuid = {C1092D92-B02C-4D89-99B1-AB312C5FCC07}
+	EndGlobalSection
+EndGlobal

+ 39 - 0
重学CPP/编译器/src/Demo/Demo/Demo.cpp

@@ -0,0 +1,39 @@
+
+#include <iostream>
+
+//extern void testX();
+
+//int ppp = 30;   // 与 T.cpp 全局数据区中定义的 ppp 变量冲突
+
+void Test();
+void Test();
+void Test();
+void Test();
+void Test();
+
+void PPInline_t();
+ 
+extern const int pt;
+
+inline int ii = 20;
+
+void Text() {
+    std::cout << "Test" << std::endl;
+}
+
+void PPInline() {
+    std::cout << ii << std::endl;
+}
+
+//void Text() {
+//    std::cout << "Test" << std::endl;
+//}
+
+int main()
+{
+    Text();
+    PPInline();
+    PPInline_t();
+    
+    std::cout << pt << std::endl;   // 输出 10
+}

+ 137 - 0
重学CPP/编译器/src/Demo/Demo/Demo.vcxproj

@@ -0,0 +1,137 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="Debug|Win32">
+      <Configuration>Debug</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|Win32">
+      <Configuration>Release</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|x64">
+      <Configuration>Debug</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|x64">
+      <Configuration>Release</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <VCProjectVersion>17.0</VCProjectVersion>
+    <Keyword>Win32Proj</Keyword>
+    <ProjectGuid>{65893cd7-7b83-4264-952b-47e4ef421f54}</ProjectGuid>
+    <RootNamespace>Demo</RootNamespace>
+    <WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <PlatformToolset>v143</PlatformToolset>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <PlatformToolset>v143</PlatformToolset>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <PlatformToolset>v143</PlatformToolset>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <PlatformToolset>v143</PlatformToolset>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <ImportGroup Label="ExtensionSettings">
+  </ImportGroup>
+  <ImportGroup Label="Shared">
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <ClCompile>
+      <WarningLevel>Level3</WarningLevel>
+      <SDLCheck>true</SDLCheck>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <ConformanceMode>true</ConformanceMode>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <ClCompile>
+      <WarningLevel>Level3</WarningLevel>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <SDLCheck>true</SDLCheck>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <ConformanceMode>true</ConformanceMode>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <ClCompile>
+      <WarningLevel>Level3</WarningLevel>
+      <SDLCheck>true</SDLCheck>
+      <PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <ConformanceMode>true</ConformanceMode>
+      <LanguageStandard>stdcpp17</LanguageStandard>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <ClCompile>
+      <WarningLevel>Level3</WarningLevel>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <SDLCheck>true</SDLCheck>
+      <PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <ConformanceMode>true</ConformanceMode>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemGroup>
+    <ClCompile Include="Demo.cpp" />
+    <ClCompile Include="T.cpp" />
+  </ItemGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets">
+  </ImportGroup>
+</Project>

+ 25 - 0
重学CPP/编译器/src/Demo/Demo/Demo.vcxproj.filters

@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup>
+    <Filter Include="源文件">
+      <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
+      <Extensions>cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
+    </Filter>
+    <Filter Include="头文件">
+      <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
+      <Extensions>h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd</Extensions>
+    </Filter>
+    <Filter Include="资源文件">
+      <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
+      <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
+    </Filter>
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="Demo.cpp">
+      <Filter>源文件</Filter>
+    </ClCompile>
+    <ClCompile Include="T.cpp">
+      <Filter>源文件</Filter>
+    </ClCompile>
+  </ItemGroup>
+</Project>

+ 4 - 0
重学CPP/编译器/src/Demo/Demo/Demo.vcxproj.user

@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup />
+</Project>

+ 10 - 0
重学CPP/编译器/src/Demo/Demo/T.cpp

@@ -0,0 +1,10 @@
+#include <iostream>
+
+extern const int pt = 10;
+//int ppp = 10;	// 与 Demo.,cpp 全局数据区的 ppp 变量冲突
+
+inline int ii = 40;
+
+void PPInline_t() {
+	std::cout << ii << std::endl;
+}