diff --git a/book/en-us/02-usability.md b/book/en-us/02-usability.md index eb8a21a..ebec0ca 100644 --- a/book/en-us/02-usability.md +++ b/book/en-us/02-usability.md @@ -147,9 +147,7 @@ we need to use the `constexpr` feature introduced in C++11, which will be introd to solve this problem; for `arr_5`, before C++98 The compiler cannot know that `len_foo()` actually returns a constant at runtime, which causes illegal production. -> Note that most compilers now have their compiler optimizations. -> Many illegal behaviors become legal under the compiler's optimization. -> If you need to reproduce the error, you need to use the old version of the compiler. +> Note that some compilers (e.g. GCC, Clang) have compiler extensions enabled by default, supporting a C feature called "[variable-length arrays](https://en.cppreference.com/w/c/language/array#Variable-length_arrays)", which allows defining an array whose length is a non-constant expression and causes the above commented out illegal code to be compilable. To disable the extension, add the compilation option [`-pedantic-errors`](https://clang.llvm.org/docs/ClangCommandLineReference.html#cmdoption-clang-pedantic-errors) (available for both GCC and Clang). C++11 provides `constexpr` to let the user explicitly declare that the function or object constructor will become a constant expression at compile time. diff --git a/book/zh-cn/02-usability.md b/book/zh-cn/02-usability.md index c39f60a..25f373b 100644 --- a/book/zh-cn/02-usability.md +++ b/book/zh-cn/02-usability.md @@ -119,7 +119,7 @@ int main() { 上面的例子中,`char arr_4[len_2]` 可能比较令人困惑,因为 `len_2` 已经被定义为了常量。为什么 `char arr_4[len_2]` 仍然是非法的呢?这是因为 C++ 标准中数组的长度必须是一个常量表达式,而对于 `len_2` 而言,这是一个 `const` 常数,而不是一个常量表达式,因此(即便这种行为在大部分编译器中都支持,但是)它是一个非法的行为,我们需要使用接下来即将介绍的 C++11 引入的 `constexpr` 特性来解决这个问题;而对于 `arr_5` 来说,C++98 之前的编译器无法得知 `len_foo()` 在运行期实际上是返回一个常数,这也就导致了非法的产生。 -> 注意,现在大部分编译器其实都带有自身编译优化,很多非法行为在编译器优化的加持下会变得合法,若需重现编译报错的现象需要使用老版本的编译器。 +> 注意,一些编译器(如 GCC、Clang)默认开启了编译器扩展,支持了 C 语言的特性:“[变长数组](https://zh.cppreference.com/w/c/language/array#.E9.9D.9E.E5.B8.B8.E9.87.8F.E9.95.BF.E5.BA.A6.E6.95.B0.E7.BB.84)”,允许定义数组时,其长度的表达式可以是非常量表达式。导致以上注释了非法的代码可以通过编译。想要禁用扩展可以添加编译选项 [`-pedantic-errors`](https://clang.llvm.org/docs/ClangCommandLineReference.html#cmdoption-clang-pedantic-errors)(GCC 与 Clang 都可用)。 C++11 提供了 `constexpr` 让用户显式的声明函数或对象构造函数在编译期会成为常量表达式,这个关键字明确的告诉编译器应该去验证 `len_foo` 在编译期就应该是一个常量表达式。