概述
前言
在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提供了三个实用的注解:
- [[fallthrough]]
- [[nodiscard]]
- [[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++新标准所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复