C++ 11——保持C99兼容性

2023-12-01 04:38
文章标签 c++ 保持 兼容性 c99

本文主要是介绍C++ 11——保持C99兼容性,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

目录

  • 保持与C99兼容
    • 预定义宏
    • __func__标识符
    • #pragma与_Pragma
    • 变长参数的宏定义以及__VA_ARGS__
    • 宽窄字符串的连接
  • 参考文献

保持与C99兼容

预定义宏

在这里插入图片描述
我们可以使用以上宏来查验机器环境对C标准和C库的支持状况:

//由于每个机器都不同,所以我在这里用xxxx来泛指
#include <iostream>
using namespace std;int main()
{cout<<"Standard Clib:"<<__STDC_HOSTED__<<endl;	//print: Standard Clib:XXXXcout<<"Standard C:"<<__STDC__<<endl;		//print: Standard C:XXXXcout<<"ISO/IEC"<<__STDC_ISO_10646__<<endl;		//print:ISO/IEC XXXXX
}

预定义宏对于多目标平台代码的编写通常具有重大意义。通过以上的宏,程序员通过使用#ifdef/#endif等预处理指令,就可使得平台相关代码只适合于当前平台的代码上编译。

__func__标识符

__func__标识符的作用就是返回所在函数的名字。

#include <string>
#include <iostream>
using namespace std;const char* hello()
{return __func__;
}const char* world()
{return __func__;
}int main()
{cout<<hello()<<" "<<world()<<endl;//print: hello world
}

利用__func__标识符,我们可以得到函数的名字。事实上,按照标准定义,编译器会隐式地在函数的定义之后定义__func__标识符

//所以说,上述函数等同于
const char* hello()
{static const char* __func__ = "hello";return __func__;
}

同时C++ 11允许其使用在类或结构体中。

#include <iostream>
using namespace std;struct TestStruct
{TestStruct():name(__func__){}const char* name;
};int main()
{TestStruct ts;cout<<ts.name<<endl;//print: TestStruct
}

我们可以看到,初始化成员列表使用__func__时可以的,但是__func__标识符作为函数默认参数是不行的,原因是这个时候__func__还未定义。

void FuncFail(string func_name = __func__);		//无法通过编译

#pragma与_Pragma

在所有预处理指令中,#pragma可以说是最复杂的了,其作用是:设定编译器的状态或者是指示编译器完成一些特定的动作。简单的说,其是用来向编译器传达语言标准以外的一些信息。

假如我们在头文件定义了以下语句:

#pragma once
//该指令指示编译器,该头文件应该只编译一次这与以下代码效果相同#ifdef THIS_HEAD
#define THIS_HEAD
#endif

其他使用可以参考百度百科。

在C++ 11中,标准定义了与预处理指令#pragma功能相同的操作符_Pragma_Pragma操作符的格式如下所示:

_Pragma(字符串字面量)
//其达到与#pragma once通用的效果只需要如下定义就可
_Pragma("once");

相比于预处理指定#pragma,由于_Pragma是一个操作符,因此可以用在一些宏中。我们可以看一下如下例子:

#define CONCAT(x) PRAGMA(concat on #x)
#define PRAGMA(x) _Pragma(#x)
CONCAT(..\concat.dir)//最终宏展开为_Pragma(concat on "..\concat.dir")

由此可见,C++ 11中的_Pragma具有更大的灵活性。

变长参数的宏定义以及__VA_ARGS__

预定义宏__VA_ARGS__可以在宏定义的实现部分替换省略号所代表的的字符串。

#include <stdio.h>#define LOG(...){\fprintf(stderr,"%s: Line %d:\t,__FILE__,__LINE__);\fprintf(stderr,__VA_ARGS__);\fprintf(stderr,"\n")\
}int main()
{int x = 3;LOG("x = %d",x);	//print:文件名:行数: x = 3
}

具体实现原理可以参考博客:运行库——变长参数

宽窄字符串的连接

在C++ 11标准中,将窄字符和宽字符进行连接时,支持C++ 11标准的编译器会将窄字符串转换成宽字符串,然后再与宽字符进行连接

参考文献

[1] IBM XL编译器中国开发团队.深入理解C++11.机械工业出版社.2013.06.
[2] #pragma.百度百科

这篇关于C++ 11——保持C99兼容性的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/439841

相关文章

深入理解C++ 空类大小

《深入理解C++空类大小》本文主要介绍了C++空类大小,规定空类大小为1字节,主要是为了保证对象的唯一性和可区分性,满足数组元素地址连续的要求,下面就来了解一下... 目录1. 保证对象的唯一性和可区分性2. 满足数组元素地址连续的要求3. 与C++的对象模型和内存管理机制相适配查看类对象内存在C++中,规

在 VSCode 中配置 C++ 开发环境的详细教程

《在VSCode中配置C++开发环境的详细教程》本文详细介绍了如何在VisualStudioCode(VSCode)中配置C++开发环境,包括安装必要的工具、配置编译器、设置调试环境等步骤,通... 目录如何在 VSCode 中配置 C++ 开发环境:详细教程1. 什么是 VSCode?2. 安装 VSCo

C++11的函数包装器std::function使用示例

《C++11的函数包装器std::function使用示例》C++11引入的std::function是最常用的函数包装器,它可以存储任何可调用对象并提供统一的调用接口,以下是关于函数包装器的详细讲解... 目录一、std::function 的基本用法1. 基本语法二、如何使用 std::function

【C++ Primer Plus习题】13.4

大家好,这里是国中之林! ❥前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站。有兴趣的可以点点进去看看← 问题: 解答: main.cpp #include <iostream>#include "port.h"int main() {Port p1;Port p2("Abc", "Bcc", 30);std::cout <<

C++包装器

包装器 在 C++ 中,“包装器”通常指的是一种设计模式或编程技巧,用于封装其他代码或对象,使其更易于使用、管理或扩展。包装器的概念在编程中非常普遍,可以用于函数、类、库等多个方面。下面是几个常见的 “包装器” 类型: 1. 函数包装器 函数包装器用于封装一个或多个函数,使其接口更统一或更便于调用。例如,std::function 是一个通用的函数包装器,它可以存储任意可调用对象(函数、函数

C++11第三弹:lambda表达式 | 新的类功能 | 模板的可变参数

🌈个人主页: 南桥几晴秋 🌈C++专栏: 南桥谈C++ 🌈C语言专栏: C语言学习系列 🌈Linux学习专栏: 南桥谈Linux 🌈数据结构学习专栏: 数据结构杂谈 🌈数据库学习专栏: 南桥谈MySQL 🌈Qt学习专栏: 南桥谈Qt 🌈菜鸡代码练习: 练习随想记录 🌈git学习: 南桥谈Git 🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈�

【C++】_list常用方法解析及模拟实现

相信自己的力量,只要对自己始终保持信心,尽自己最大努力去完成任何事,就算事情最终结果是失败了,努力了也不留遗憾。💓💓💓 目录   ✨说在前面 🍋知识点一:什么是list? •🌰1.list的定义 •🌰2.list的基本特性 •🌰3.常用接口介绍 🍋知识点二:list常用接口 •🌰1.默认成员函数 🔥构造函数(⭐) 🔥析构函数 •🌰2.list对象

06 C++Lambda表达式

lambda表达式的定义 没有显式模版形参的lambda表达式 [捕获] 前属性 (形参列表) 说明符 异常 后属性 尾随类型 约束 {函数体} 有显式模版形参的lambda表达式 [捕获] <模版形参> 模版约束 前属性 (形参列表) 说明符 异常 后属性 尾随类型 约束 {函数体} 含义 捕获:包含零个或者多个捕获符的逗号分隔列表 模板形参:用于泛型lambda提供个模板形参的名

6.1.数据结构-c/c++堆详解下篇(堆排序,TopK问题)

上篇:6.1.数据结构-c/c++模拟实现堆上篇(向下,上调整算法,建堆,增删数据)-CSDN博客 本章重点 1.使用堆来完成堆排序 2.使用堆解决TopK问题 目录 一.堆排序 1.1 思路 1.2 代码 1.3 简单测试 二.TopK问题 2.1 思路(求最小): 2.2 C语言代码(手写堆) 2.3 C++代码(使用优先级队列 priority_queue)

高并发环境中保持幂等性

在高并发环境中保持幂等性是一项重要的挑战。幂等性指的是无论操作执行多少次,其效果都是相同的。确保操作的幂等性可以避免重复执行带来的副作用。以下是一些保持幂等性的常用方法: 唯一标识符: 请求唯一标识:在每次请求中引入唯一标识符(如 UUID 或者生成的唯一 ID),在处理请求时,系统可以检查这个标识符是否已经处理过,如果是,则忽略重复请求。幂等键(Idempotency Key):客户端在每次