Skip to content

Commit

Permalink
book: fix imprecise description of NULL in C++ (#279)
Browse files Browse the repository at this point in the history
  • Loading branch information
frederick-vs-ja authored May 20, 2024
1 parent ff6ee89 commit bdf0e89
Show file tree
Hide file tree
Showing 2 changed files with 11 additions and 10 deletions.
17 changes: 9 additions & 8 deletions book/en-us/02-usability.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,20 +18,21 @@ which refers to the language behavior that occurred before the runtime.

### nullptr

The purpose of `nullptr` appears to replace `NULL`. In a sense,
traditional C++ treats `NULL` and `0` as the same thing,
depending on how the compiler defines NULL,
and some compilers define NULL as `((void*)0)` Some will define it directly as `0`.
The purpose of `nullptr` appears to replace `NULL`. There are **null pointer constants** in the C and C++ languages,
which can be implicitly converted to null pointer value of any pointer type,
or null member pointer value of any pointer-to-member type in C++.
`NULL` is provided by the standard library implementation and defined as an implementation-defined null pointer constant.
In C, some standard libraries defines `NULL` as `((void*)0)` and some define it as `0`.

C++ **does not allow** to implicitly convert `void *` to other types.
But if the compiler tries to define `NULL` as `((void*)0)`, then in the following code:
C++ **does not allow** to implicitly convert `void *` to other types, and thus `((void*)0)` is not a valid implementation
of `NULL`. If the standard library tries to define `NULL` as `((void*)0)`, then compilation error would occur in the following code:

```cpp
char *ch = NULL;
```

C++ without the `void *` implicit conversion has to define `NULL` as `0`.
This still creates a new problem. Defining `NULL` to 0 will cause the overloading feature in `C++` to be confusing.
This still creates a new problem. Defining `NULL` to `0` will cause the overloading feature in `C++` to be confusing.
Consider the following two `foo` functions:

```cpp
Expand All @@ -41,7 +42,7 @@ void foo(int);
Then the `foo(NULL);` statement will call `foo(int)`, which will cause the code to be counterintuitive.
To solve this problem, C++11 introduced the `nullptr` keyword, which is specifically used to distinguish null pointers, 0. The type of `nullptr` is `nullptr_t`, which can be implicitly converted to any pointer or member pointer type, and can be compared equally or unequally with them.
To solve this problem, C++11 introduced the `nullptr` keyword, which is specifically used to distinguish null pointers, `0`. The type of `nullptr` is `nullptr_t`, which can be implicitly converted to any pointer or member pointer type, and can be compared equally or unequally with them.
You can try to compile the following code using clang++:
Expand Down
4 changes: 2 additions & 2 deletions book/zh-cn/02-usability.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@ order: 2

### nullptr

`nullptr` 出现的目的是为了替代 `NULL`在某种意义上来说,传统 C++ 会把 `NULL``0` 视为同一种东西,这取决于编译器如何定义 `NULL`,有些编译器会将 `NULL` 定义为 `((void*)0)`,有些则会直接将其定义为 `0`
`nullptr` 出现的目的是为了替代 `NULL` C 与 C++ 语言中有**空指针常量**,它们能被隐式转换成任何指针类型的空指针值,或 C++ 中的任何成员指针类型的空成员指针值。 `NULL` 由标准库实现提供,并被定义为实现定义的空指针常量。在 C 中,有些标准库会把 `NULL` 定义为 `((void*)0)` 而有些将它定义为 `0`

C++ **不允许**直接将 `void *` 隐式转换到其他类型。但如果编译器尝试把 `NULL` 定义为 `((void*)0)`那么在下面这句代码中
C++ **不允许**直接将 `void *` 隐式转换到其他类型,从而 `((void*)0)` 不是 `NULL` 的合法实现。如果标准库尝试把 `NULL` 定义为 `((void*)0)`那么下面这句代码中会出现编译错误

```cpp
char *ch = NULL;
Expand Down

0 comments on commit bdf0e89

Please sign in to comment.