首页 > 编程语言 >C++ 宏

C++ 宏

时间:2023-02-03 23:01:31浏览次数:64  
标签:__ 定义 int MAX C++ 编译器 TYPE

目录

标识符 ___ 的含义

以单下划线(_)表明是标准库的变量

双下划线(__) 开头表明是编译器的变量

所以建议自己在命名的时候就不要用下划线开头,避免与标准库中的命名冲突了

C++内置宏定义

1. 标准内置宏定义

标准内置宏定义是由相关的语言标准定义的,因此对于实现了这些语言标准的编译器来说都是可使用的。

  • __FILE__:字符串格式,指示当前处理的文件路径。
  • __LINE__:数字格式,指示当前处理的代码行号。
  • #line:用来修改当前行的下一行的行号,即下一行的 __LINE__#line 所指定的数字开始。
#include<stdio.h>

int main()
{
	printf("Line: %d\n", __LINE__);		// 5
	#line 100
	printf("Line: %d\n", __LINE__);	 	// 100
	return 0;
}

【注】__FILE____LINE__ 宏主要用于错误处理,可以很方便地定位错误位置。

  • C99 引入了 __func__,它和 GCC 提供的 __FUNCTION__ 功能类似,二者都是字符串格式,指示当前处理的函数名。

【注】__func____FUNCTION__ 本质上都不是宏,因为预处理器并不知道当前处理的函数名。

  • __DATE__:字符串格式,指示预处理器处理当前代码时的日期。
  • __TIME__:字符串格式,指示预处理器处理当前代码时的时间。
  • __STDC__:常数格式,一般值为 1,用来告诉编译器遵守 ISO 标准 C 格式。
  • __STDC_VERSION__:常数格式,指示当前使用的 C 语言标准版本,格式为 yyyymmL,其中 yyyymm 分别表示年份和月份。
  • __STDC_HOSTED__:数字格式,1 表示要编译的对象是一个 Hosted Environment,否则表示不是。

【注】一个 Hosted Environment 表示具有可用的标准 C 库的完整功能。

  • __cplusplus:当使用了 C++ 编译器时,该宏被定义。因此可以它来测试编译时使用的编译器是 C 编译器还是 C++ 编译器。当 __cplusplus 被定义时,其格式和 __STDC_VERSION__ 类似,只不过指示的是 C++ 语言的标准版本号。
  • __OBJC__:当使用了 Objective-C 编译器时,该宏被定义。因此可以它来测试编译时使用的编译器是 C 编译器还是 Objective-C 编译器。当 __OBJC__ 被定义时,其格式和 __STDC_VERSION__ 类似,只不过指示的是 Objective-C 语言的标准版本号。
  • __ASSEMBLER__:当预处理汇编语言时,该宏被定义。

2. 公共内置宏定义

公共内置宏定义是 GNU C 的扩展,只要使用了 GNU C 或者 GNU Fortran,这些宏都是可使用的。公共内置宏定义数量繁多,因此仅介绍常用的一些宏,更多可以参见官方文档:Common Predefined Macros

  • __COUNTER__:累加器,每次使用一次就递增 1。因此可以用来当作唯一标识符使用。
  • __GNUC____GNUC_MINOR____GNUC_PATCHLEVEL__:这些宏在使用了 C 预处理器的所有编译器中都定义了。它们分别指示了编译器的主版本号、次版本号和补丁版本号,均为整数常数。
  • __BASE_FILE__:字符串格式,指示了主文件的路径。
  • __FILE_NAME__:字符串格式,指示了当前文件路径的 Basename,即文件名。
  • __INCLUDE_LEVEL__:数字格式,指示了当前嵌套深度。从 0 开始,每进入一次 #include 指示的头文件,__INCLUDE_LEVEL__ 增加 1
  • __VERSION__:字符串格式,指示了编译器的版本号。
  • __OPTIMIZE____OPTIMIZE_SIZE____NO_INLINE__:这些宏描述了编译模式。__OPTIMIZE__ 在所有的优化编译中都定义了,比如 O1O2 等优化模式下;当编译器优化文件大小而不是运行速度时,__OPTIMIZE_SIZE__ 被定义;当编译器内联展开被禁止时,__NO_INLINE__ 被定义。
  • __CHAR_UNSIGNED____WCHAR_UNSIGNED__:GCC 定义了宏 __CHAR_UNSIGNED____WCHAR_UNSIGNED__ 当且仅当数据类型 charwchat_t 在目标主机上是无符号类型。
  • __CHAR_BIT__:数字格式,表示一个 char 数据类型占用多少 bit。
  • __BYTE_ORDER____ORDER_LITTLE_ENDIAN____ORDER_BIG_ENDIAN____ORDER_PDP_ENDIAN____BYTE_ORDER__ 取值只能是 __ORDER_LITTLE_ENDIAN____ORDER_BIG_ENDIAN____ORDER_PDP_ENDIAN__ 中的一种。表示多字节/字数据的存储模式,__ORDER_LITTLE_ENDIAN____ORDER_BIG_ENDIAN__ 即大小端模式,而 __ORDER_PDP_ENDIAN__ 表示对于 16 位的字按照小端模式存储,对于 32 位双字中的 16 位子字是按照大端模式存储的。
  • __FLOAT_WORD_ORDER__:表示浮点双字的存储模式,其值只能取 __ORDER_LITTLE_ENDIAN____ORDER_BIG_ENDIAN__ 中的一种。

GCC 定义了一批和数据类型对应的宏,如下表所示:

数据类型 数据类型宏
size_t SIZE_TYPE
ptrdiff_t PTRDIFF_TYPE
wchar_t WCHAR_TYPE
wint_t WINT_TYPE
intmax_t INTMAX_TYPE
uintmax_t UINTMAX_TYPE
sig_atomic_t SIG_ATOMIC_TYPE
int8_t INT8_TYPE
int16_t INT16_TYPE
int32_t INT32_TYPE
int64_t INT64_TYPE
uint8_t UINT8_TYPE
uint16_t UINT16_TYPE
uint32_t UINT32_TYPE
uint64_t UINT64_TYPE
int_least8_t INT_LEAST8_TYPE
int_least16_t INT_LEAST16_TYPE
int_least32_t INT_LEAST32_TYPE
int_least64_t INT_LEAST64_TYPE
uint_least8_t UINT_LEAST8_TYPE
uint_least16_t UINT_LEAST16_TYPE
uint_least32_t UINT_LEAST32_TYPE
uint_least64_t UINT_LEAST64_TYPE
int_fast8_t INT_FAST8_TYPE
int_fast16_t INT_FAST16_TYPE
int_fast32_t INT_FAST32_TYPE
int_fast64_t INT_FAST64_TYPE
uint_fast8_t UINT_FAST8_TYPE
uint_fast16_t UINT_FAST16_TYPE
uint_fast32_t UINT_FAST32_TYPE
uint_fast64_t UINT_FAST64_TYPE
intptr_t INTPTR_TYPE
uintptr_t UINTPTR_TYPE

GCC 定义了一批表示数据类型最大/小值的宏,如下表所示:

数据类型 数据类型最大值宏
signed char SCHAR_MAX
wchar_t WCHAR_MAX
signed short SHRT_MAX
signed int INT_MAX
signed long LONG_MAX
signed long long LONG_LONG_MAX
wint_t WINT_MAX
size_t SIZE_MAX
ptrdiff_t PTRDIFF_MAX
intmax_t INTMAX_MAX
uintmax_t UINTMAX_MAX
sig_atomic_t SIG_ATOMIC_MAX
int8_t INT8_MAX
int16_t INT16_MAX
int32_t INT32_MAX
int64_t INT64_MAX
uint8_t UINT8_MAX
uint16_t UINT16_MAX
uint32_t UINT32_MAX
uint64_t UINT64_MAX
int_least8_t INT_LEAST8_MAX
int_least16_t INT_LEAST16_MAX
int_least32_t INT_LEAST32_MAX
int_least64_t INT_LEAST64_MAX
uint_least8_t UINT_LEAST8_MAX
uint_least16_t UINT_LEAST16_MAX
uint_least32_t UINT_LEAST32_MAX
uint_least64_t UINT_LEAST64_MAX
int_fast8_t INT_FAST8_MAX
int_fast16_t INT_FAST16_MAX
int_fast32_t INT_FAST32_MAX
int_fast64_t INT_FAST64_MAX
uint_fast8_t UINT_FAST8_MAX
uint_fast16_t UINT_FAST16_MAX
uint_fast32_t UINT_FAST32_MAX
uint_fast64_t UINT_FAST64_MAX
intptr_t INTPTR_MAX
uintptr_t UINTPTR_MAX
wchar_t WCHAR_MIN
wint_t WINT_MIN
sig_atomic_t SIG_ATOMIC_MIN

GCC 还定义了一批表示数据类型占用字节数的宏,如下表所示:

数据类型 数据类型占用字节数宏
int SIZEOF_INT
long SIZEOF_LONG
long long SIZEOF_LONG_LONG
short SIZEOF_SHORT
void * SIZEOF_POINTER
float SIZEOF_FLOAT
double SIZEOF_DOUBLE
long double SIZEOF_LONG_DOUBLE
size_t SIZEOF_SIZE_T
wchar_t SIZEOF_WCHAR_T
wint_t SIZEOF_WINT_T
ptrdiff_t SIZEOF_PTRDIFF_T

【注】在某些特定系统上,GCC 如果没有提供 stdint.h 头文件,则上表中的某些数据类型对应的宏可能就未被定义。

2.1 查看 GCC 所有内置宏定义

如果想要查看当前系统下的 GCC 所有内置宏定义,可以使用以下命令:

gcc -dM -E - < /dev/null

2.2 查看 G++ 所有内置宏定义

如果想要查看当前系统下的 G++ 所有内置宏定义,可以使用以下命令:

g++ -dM -E -x c++ - < /dev/null

3. 系统内置宏定义

对于某些特定系统本身内置的一些宏,GCC 提供和其等价的宏,等价宏的命名在原有宏名称基础上,首尾加上一个或多个下划线,保证首尾下划线数均为 2。比如 Unix 系统的 unix 宏,则 GCC 提供 __unix__ 宏;而对于 _mpis 宏,则 GCC 提供 __mips__ 宏。

4. 内置操作符宏定义

C++ 定义了 11 个操作符宏,如下表所示:

操作符 操作符宏
&& and
&= and_eq
& bitand
| bitor
~ compl
! not
!= not_eq
|| or
|= or_eq
^ xor
^= xor_eq

如果想要在 C 语言中使用 C++ 中定义的这 11 个操作符宏,可以引入 iso646.h 头文件。

windows平台特有宏

1、WIN32宏

在 Win32 配置下,WIN32 在“项目属性-C/C++-预处理器-预处理器定义”里声明了,而在 x64 配置下,这个常量并不在项目预定义列表中。这是否说明可以根据 WIN32 来判断是否在 x64 平台呢?不。在 Windows SDK 的 minwindef.h 下第 37 行有如下定义:

#ifndef WIN32
#define WIN32
#endif

即是说,只要包含了 Windows.h,那么 WIN32 常量是肯定定义了的,所以不能用于判断平台环境。但是如果在预处理定义里删掉 WIN32,又不包含 Windows.h,那么 WIN32 未定义

2、_WIN32,_WIN64

_WIN32 和 _WIN64,这两个比较特别,没有任何显式定义。在 Windows.h 里没有,在“项目属性-C/C++-预处理器-预处理器定义”下也没有。根据 MSDN,这是由编译器(ml.exe/ml64.exe)内部定义的。具体描述是

​ _WIN32:Defined for applications for Win32 and Win64. Always defined.
​ _WIN64:Defined for applications for Win64.

3、总结

WIN32宏 --只要包含了 Windows.h,那么 WIN32 常量是肯定定义了的,所以不能用于判断平台环境

_WIN32 --32位和64位程序都有,且总是定义的.

_WIN64 --只有64位程序才有

常用代码:

(1)判断是不是windows平台

#if _WIN32 || WIN32  //windows平台
...
#else 
...
#endif

(2)判断是不是64位环境还是32位

#ifdef _WIN64
 
#ifdef _DEBUG
#pragma comment(lib, "*x64d.lib")
#else
#pragma comment(lib, "*x64r.lib")
#endif
 
#else
 
#ifdef _DEBUG
#pragma comment(lib, "*x86d.lib")
#else
#pragma comment(lib, "*x86r.lib")
#endif
 
#endif

错误案例

#ifdef WIN32
 
#ifdef _DEBUG
#pragma comment(lib, "*x86d.lib")
#else
#pragma comment(lib, "*x86r.lib")
#endif
 
#else
 
#ifdef _DEBUG
#pragma comment(lib, "*x64d.lib")
#else
#pragma comment(lib, "*x64r.lib")
#endif
 
#endif

标签:__,定义,int,MAX,C++,编译器,TYPE
From: https://www.cnblogs.com/hhddd-1024/p/17090656.html

相关文章

  • c++虚拟内存
    可以通过调用vmemalloc类型对象的括号运算符(len,name)分配大小为len,文件名为name的虚拟内存。返回首地址的迭代器。无需delete,程序结束后会自动清空文件,但是保留文件名#......
  • 代码随想录-数组-C++总结
    1.二分查找重点区分左闭右开,左闭右闭两种写法中的差异,理解循环中的不变量,这样在returnr还是l和什么时候l+1r-1什么时候不需要+1-1很重要。35.搜索插入位置-力扣(Leet......
  • C++ 1398:短信计费
    1398:短信计费【题目描述】用手机发短信,一条短信资费为0.1元,但限定一条短信的内容在70个字以内(包括70个字)。如果你一次所发送的短信超过了70个字,则会按照每70个字一条......
  • C++1155:回文三位数
    1155:回文三位数【题目描述】如果一个数从左边读和从右边读都是同一个数,就称为回文数。例如6886就是一个回文数,求出所有的既是回文数又是素数的三位数。【输入】(......
  • C++开发面试题合集
    1.epoll的工作原理(【360实习】C++开发)epoll是一种I/O事件通知机制,是linux内核实现IO多路复用的一个实现。在一个操作里同时监听多个输入输出源,在其中一个或多个输入输出......
  • C++ 哈希表查询_进入哈希函数结界的世界
    1.前言哈希表或称为散列表,是一种常见的、使用频率非常高的数据存储方案。哈希表属于抽象数据结构,需要开发者按哈希表数据结构的存储要求进行API定制,对于大部分高级语言......
  • C++第四章类与对象
    一、面向对象的基本特点1.  抽象对同一类对象的共同属性和行为进行概括,形成类。先注意问题的本质及描述,其次是实现过程或细节。数据抽象:描述某类对象的属性或状态(对象相互......
  • 【八大数据排序法】希尔排序法的图形理解和案例实现 | C++
    第十七章希尔排序法:::hljs-center目录第十七章希尔排序法●前言●认识排序●一、希尔排序法是什么?1.简要介绍2.图形理解3.算法分析●二、案例实现1.......
  • c++中调用QML中的函数和设置QML中的属性的问题
    1.这里主要是介绍,如何在c++中调用QML中的函数和设置QML中的属性的问题  2.具体代码    //UICtest.qmlimportQt4.7Rectangle{   id:mainWid......
  • C/C++编译链接
    一、编译链接过程名词解释编译:由编译器对各个源文件进行词法分析、语法分析、语义分析等操作,最终生成多个目标文件。由于这些文件可能存在互相调用对方的函数或变量,还......