您的位置: 首页 - 站长

做电脑网站建e室内设计网全景分类

当前位置: 首页 > news >正文

做电脑网站,建e室内设计网全景分类,重庆网站平台,凡科送审平台学生不能登录预处理和编译 条件编译源代码使用方式典型示例原理 使用static_assert执行编译时断言检查使用方式原理 在C中#xff0c;编译是将源代码转换为机器代码并组织在目标文件中#xff0c;然后将目标文件链接在一起生成可执行文件的过程。编译器实际上一次只处理一个文件#xff… 预处理和编译 条件编译源代码使用方式典型示例原理 使用static_assert执行编译时断言检查使用方式原理 在C中编译是将源代码转换为机器代码并组织在目标文件中然后将目标文件链接在一起生成可执行文件的过程。编译器实际上一次只处理一个文件这个文件是由预处理器编译器中处理预处理指令的部分从单个源文件及其包含的所有头文件中生成的。 条件编译源代码 条件编译使开发人员能够维护单个代码库但只考虑编译代码的某些部分以生成不同的可执行文件通常是为了在不同的平台或硬件上运行或依赖于不同的库或版本。 使用方式 若要条件编译部分代码可以使用#if、#ifdef和#ifndef指令与#elif、#else和#endif指令一起。条件编译的一般形式如下 #if condition1text1 #elif condition2text2 #elif condition3text3 #elsetext4 #endif要定义用于条件编译的宏可以使用以下方法之一 在源代码中使用#define指令 #define VERBOSE_PRINTS #define VERBOSITY_LEVEL 5使用编译器命令行选项 对于g而言-D是一个选项用于在编译时定义宏 main.cpp #include iostreamint main() {std::cout Hello, World! std::endl;#ifdef DEBUGstd::cout Debug mode is enabled. std::endl;#elsestd::cout Debug mode is disabled. std::endl;#endifreturn 0; }编译指令定义宏DEBUG g -DDEBUG main.cpp -o main输出Debug mode is enabled. 普通编译 g main.cpp -o main输出Debug mode is disabled.
典型示例 头文件保护避免重复定义 现在更多的使用pragma once #ifndef HEADER_NAME #define HEADER_NAMEclass A {} #endif两者都可以实现头文件的防重复包含但前者适用于所有遵循C/C预处理器约定的编译器后者则依赖于编译器的支持。 针对跨平台应用程序 将带有编译器名称的消息打印到控制台 void show_compiler() { #if defined _MSC_VERcout VC\n; #elif defined clangcout Clang\n; #elif defined GNUGcout GCC\n; #elsecout unknown compiler\n; #endif }针对多个架构的目标特定代码 void show_architecture() { #if defined _MSC_VER#if defined _M_X64std::cout AMD64;#elif defined _M_IX86std::cout INTEL x86;#elif defined _M_ARMstd::cout ARM;#elsestd::cout unknown;#endif #elif defined clang || GNUC#if defined amd64std::cout AMD64;#elif defined i386std::cout INTEL x86;#elif defined armstd::cout ARM;#elsestd::cout unknown;#endif #else#error Unknown compiler #endif }特定于配置的代码 有条件地编译调试和发布版本 void show_configuration() { #ifdef _DEBUGcout debug\n; #else cout release\n; #endif }原理 当使用预处理指令#if、#ifndef、#ifdef、#elif、#else和#endif时编译器将至多选择一个分支其主体将包含在编译单元中。这些指令的主体可以是任何文本包括其他预处理指令。适用规则如下 #if、#ifdef和#ifndef必须用#endif匹配。#if指令可以有多条#elif指令但只有一条#else指令且#else必须是#endif之前的最后一条。#if、#ifdef、#ifndef、#elif、#else和#endif可以嵌套。#if指令需要一个常量表达式而#ifdef和#ifndef则需要一个标识符。defined操作符可以用于预处理器常量表达式但只能在#if和#elif指令中使用。defined(identifier)在定义identifier时为true否则它被认为是false。定义为空文本的标识符被认为是有定义的。#ifdef identifier等价于#if defined(identifier)。#ifndef identifier等价于#if !defined(identifier)。defined(identifier)和defined identifier是等价的。宏的名称在整个应用程序中必须是唯一的否则将只编译使用宏的第一个头文件中的代码 使用static_assert执行编译时断言检查 C可以同时执行运行时和编译时断言检查。注意C版本需要高于C11才会出现编译错误 运行时断言只有在程序运行时并且只有在控制流到达它们时才会被验证。当条件依赖于运行时数据时只能选择运行时断言。编译时断言(条件可以在编译时求值)能够在开发阶段的早期通知某个特定条件未被满足。在C11中编译时断言是通过static_assert执行的。静态断言检查常在模板元编程中用于验证模板类型的先决条件是否满足例如类型是否为POD类型、可复制构造类型、引用类型等。另一个典型用例是确保类型或对象具有预期的大小。 使用方式 使用 static_assert 声明来确保满足以下作用域中的条件 命名空间作用域本例验证item类的大小总是16 struct alignas(8) item {int id;bool active;double value;/* data / };static_assert(sizeof(item) 16,size of item must be 16 types);类作用域本例验证pod_wrapper只能与POD类型一起使用 is_standard_layout_v 是 C 标准库 type_traits 中的一个模板元函数它用于在编译时判断一个类型是否是标准布局类型。标准布局类型需要满足一系列规则这些规则包括 没有虚函数包括虚析构函数没有虚基类所有非静态成员都是标准布局类型非静态成员之间没有相同的名称类的继承关系中没有相同的基类满足其他一些与对齐和大小相关的规则 template typename T class pod_wrapper {static_assert(std::is_standard_layout_vT,POD type expected!);T value; };struct point {int x;int y;/ data */ }; pod_wrapperint w1; //ok pod_wrapperpoint w2; //ok pod_wrapperstd::string w3; //err函数块作用域本例验证函数模板是否只有整型参数 #include type_traitstemplate typename T auto mul(T const a, T const b) {static_assert(std::is_integral_vT::value,Integral type expected);return a * b; } auto v1 mul(1, 2); //ok auto v2 mul(1.2, 3.4); //err原理 static_assert是一个声明但它没有引入新名称。这些声明的形式如下 static_assert(condition, message);该条件必须在编译时转换为布尔值且消息必须是字符串字面量。在C17中该消息是可选的。当static_assert声明中的条件计算结果为true时什么都不会发生当条件的计算结果为false时编译器生成一个包含指定消息如果有的话的错误。