我是靠谱客的博主 温暖可乐,最近开发中收集的这篇文章主要介绍C++必知必会:C++17注解标签(attributes)前言C++98/03得enumeration和C++11的enumeratorC++17注解标签查看C++新标准,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

前言

在C++98/03时代,不同的编译器使用不同的注解为代码增加了一些额外的说明,比如常见的#pragma, __declspec, __attribute等。从C++11开始,新的语言标准统一制定了一些常用的注解标签,所以在这里介绍几种常用的。
使用注解标签得语法如下:

[[attribute]] types/functions/enums/etc

这些标签可以修饰任意类型、函数或者enumeration,在C++17之前不能修饰命名空间和 enumerator,在C++17后这个限制也被取消。

文章目录

  • 前言
  • C++98/03得enumeration和C++11的enumerator
  • C++17注解标签
    • C++11noreturn
    • C++14 deprecated
    • C++17
  • 查看C++新标准

C++98/03得enumeration和C++11的enumerator

enumeration和enumerator,前者是指从C时代就存在的不限定作用域的枚举。示例:

// 一个enumeration例子
enum Color
{
	black,
	white,
	red
};

// 无法编译通过
bool white = true;

这种枚举类型被称为不限定作用域枚举,因为一旦定义了这样的一种枚举,在其所在的作用域内就不能再定义与之同名的变量了。

而enumerator指的是从C++11开始引入的以如下形式定义的枚举变量:

// 一个enumerator示例
enum class Color
{
	black,
	white,
	red
};

// 可以编译通过
bool white = true;

此时,由于枚举值white对外部不可见(需要使用Color::white引用),所以可以定义一个同名的white变量。
这种枚举变量被称为限定作用域枚举。

C++17注解标签

C++11noreturn

C++11引入的常用注解标签有 [[noreturn]],这个注解的含义是告诉编译器某个函数没有返回值。 示例:

[[noreturn]] void function1()

这个标签一般在设计一些系统函数时使用,例如std::abort()和std::exit()。

C++14 deprecated

C++14引入了[[deprecated]]标签来表示一个函数或者类型等已经被弃用,在使用这些被弃用的函数或类型并编译时,编译器会发出相应的警告,也可以使用以下语法,给出编译时的具体警告或者出错信息。

[[deprecated("use function3 instead")]] void function2() {}

void function3() {}

C++17

C++17提供了三个实用的注解:

  1. [[fallthrough]]
  2. [[nodiscard]]
  3. [[maybe_unused]]

第一个用于 switch-case语句中,在某个case执行完毕后如果没有break语句,则编译器可能会给出警告,但这可能是开发者有意为之的,为了让编译器知道开发者的意图,可以在需要某个case分支被“贯穿”的地方显式设置[[fallthrough]]标记。

来看看源代码:

#ifndef __fallthrough // [
#if (!defined(_MSVC_LANG) || _MSVC_LANG < 201703l) // [
    __inner_fallthrough_dec
    #define __fallthrough __inner_fallthrough
#else // ][
    #define __fallthrough [[fallthrough]]
#endif // ]
#endif // ]

使用示例:

int main(void)
{
	switch (1)
	{
	case 1:
		function1();
		// 缺少break,没有fallthrough标注,
		// 可能是一个逻辑错误,编译器会给出警告
	case 2:
		function2();
		__fallthrough;
		// 这里缺少break,但有该标注,说明是开发者有意为之
	}
}

[[nodiscard]]一般用于修饰函数,告诉函数调用者必须关注该函数的返回值(即不能丢弃该函数的返回值)。如果函数调用者未将该函数的返回值赋给一个变量,则编译器会给出一个警告。

比如网络连接函数connect()是根据返回值来说明是否建立成功,则为了防止调用者在使用时直接将该值丢弃,就是用该标记。

[[nodiscard]] int connect(const char* address, short port) {}

在通常情况下,编译器会对程序代码中未使用的函数或变量给出警告,另一些编译器干脆不允许通过编译。在C++17之前,为了消除这些未使用的变量带来的编译警告或错误,要么修改编译器的警告选项设置,要么定义一个类似于UNREFERENCED_PARAMETER的宏来显式调用这些未使用的变量依次,以消除编译警告:

#define UNREFERENCED_PARAMETER(x) x

int APIENTRY wWinMain(HINSTANCE hInstance,
	HINSTANCE hPrevInstance,
	LPWSTR	lpCmdLine,
	int		nCmdShow)
{
	UNREFERENCED_PARAMETER(hPrevInstance);
	UNREFERENCED_PARAMETER(lpCmdLine);
}

上面是一个Win32程序的结构,其中的函数参数hPrevInstance 和lpCmdLine一般不会用到,为了消除警告,定义了一个宏,造成这两个参数被使用的假象。

有了[[maybe_unused]]后,就不再需要这些宏来欺骗编译器了。

int APIENTRY wWinMain(HINSTANCE hInstance,
	[[maybe_unused]] HINSTANCE hPrevInstance,
	[[maybe_unused]] LPWSTR	lpCmdLine,
	int		nCmdShow)
{
}

查看C++新标准

#if defined(deprecated)
#define deprecated EMIT WARNING C4005
#error The C++ Standard Library forbids macroizing the attribute-token "deprecated". 
Enable warning C4005 to find the forbidden define.
#endif // deprecated

#if defined(fallthrough) && _HAS_CXX17
#define fallthrough EMIT WARNING C4005
#error The C++ Standard Library forbids macroizing the attribute-token "fallthrough". 
Enable warning C4005 to find the forbidden define.
#endif // fallthrough

// not checking "likely" because it is commonly defined as a function-like macro

#if defined(maybe_unused) && _HAS_CXX17
#define maybe_unused EMIT WARNING C4005
#error The C++ Standard Library forbids macroizing the attribute-token "maybe_unused". 
Enable warning C4005 to find the forbidden define.
#endif // maybe_unused

#if defined(nodiscard) // C++17 attribute-token, also enforced in C++14 mode
#define nodiscard EMIT WARNING C4005
#error The C++ Standard Library forbids macroizing the attribute-token "nodiscard". 
Enable warning C4005 to find the forbidden define.
#endif // nodiscard

#if defined(noreturn)
#define noreturn EMIT WARNING C4005
#error The C++ Standard Library forbids macroizing the attribute-token "noreturn". 
Enable warning C4005 to find the forbidden define.
#endif // noreturn

最后

以上就是温暖可乐为你收集整理的C++必知必会:C++17注解标签(attributes)前言C++98/03得enumeration和C++11的enumeratorC++17注解标签查看C++新标准的全部内容,希望文章能够帮你解决C++必知必会:C++17注解标签(attributes)前言C++98/03得enumeration和C++11的enumeratorC++17注解标签查看C++新标准所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(54)

评论列表共有 0 条评论

立即
投稿
返回
顶部