Skip to content

Commit

Permalink
docs: 📝 fix wrong NULL explanation
Browse files Browse the repository at this point in the history
  • Loading branch information
DragonAura authored and Timothy-Liuxf committed Jul 16, 2023
1 parent 7f67e7a commit 30dfa2c
Showing 1 changed file with 13 additions and 1 deletion.
14 changes: 13 additions & 1 deletion docs/languages/C&C++/modern_cpp.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,23 @@ title: Modern C++ 选讲
替代 NULL。C++11 引入了 `nullptr` 关键字,专门用来区分空指针、`0`。而 `nullptr` 的类型为 `nullptr_t`,能够隐式的转换为任何指针或成员指针的类型。

```C++
void foo(int);
void foo(char*);

foo(0); // 调用 foo(int)
// foo(NULL); // 该行不能通过编译
// foo(NULL); // 该行在不同编译器下会有不同的行为,可以参考下面的说明。
foo(nullptr); // 调用 foo(char*)
```
> 在 C++11 之后的标准中,`NULL` 可以是一个整数类型的 0,也可以是一个 `std::nullptr_t`。因此,类似下面的两种编译器实现都是可以的。
> ```c++
> #define NULL 0
> #define NULL nullptr
> ```
> 在 msvc 中,`NULL` 的实现为 `#define NULL 0`,因此上面的代码是可以通过编译的;而在 gcc 和 clang 中,`NULL` 的实现为 `#define NULL __null`,此处 `__null` 是一个 `long` 类型的 0,同样是符合标准的。
>
> 因此,对于 `foo(NULL)` 而言,`foo(int)` 和 `foo(char*)` 都不是精确的参数类型匹配,因此不能通过编译(会提示 `foo` 的调用是不明确的);而如果加入 `void foo(long);` 的声明,则 `foo(NULL)` 精确地匹配到了 `foo(long)`,因此可以通过编译。
### constexpr
显式声明常量表达式。const 修饰的变量**只在一定情况下**是常量表达式,这有时可能带来困扰。C++11 提供了 `constexpr` 让用户显式的声明函数或对象构造函数**在编译期**会成为常量表达式。 从 C++14 开始,`constexpr` 函数可以在内部使用局部变量、循环和分支等简单语句。
Expand Down

0 comments on commit 30dfa2c

Please sign in to comment.