为什么 GNU C++ 编译器允许你修改常量?
Why does GNU C++ compiler allow you to modify a constant?
我正在通过 GDB 调试一个用 C++ 编写的项目,发现 GNU C++ 编译器在没有警告或错误的情况下修改了一个 const。
这不是我正在调试的程序,但这是我目睹的行为示例:
#include <iostream>
int main(int argc, char *argv[]) {
const int x = 10;
int *px = (int *)&x;
++*px;
std::cout << "*px: " << *px << "\n";
std::cout << "x: " << x << "\n";
for (int i = 0; i < x; ++i)
std::cout << i+1 << "\n";
return 0;
}
我不能代表其他编译器,因为我只用 GNU C++ 编译器 4.9.2 版对此进行了测试。为什么允许这样的事情?这打破了 const
个对象的整个点。
我用g++编译了上面的代码main.c -Wall -Werror
输出:
*px: 11
x: 10
1
2
3
4
5
6
7
8
9
10
就编译器而言,您不是在修改常量。您正在修改指向非常量 int
的指针指向的内容,因为这就是强制转换 (int *)
告诉编译器将 &x
视为。
这种所谓的 C 风格转换是 C++ 提供的最强大的转换。铸造通常只应在真正必要的范围内进行。很多时候,const_cast
、static_cast
、dynamic_cast
就足够了(还有比较厉害的reinterpret_cast
)。
C 风格转换的行为是应用允许编译成功所需的最不强大的转换。
我正在通过 GDB 调试一个用 C++ 编写的项目,发现 GNU C++ 编译器在没有警告或错误的情况下修改了一个 const。
这不是我正在调试的程序,但这是我目睹的行为示例:
#include <iostream>
int main(int argc, char *argv[]) {
const int x = 10;
int *px = (int *)&x;
++*px;
std::cout << "*px: " << *px << "\n";
std::cout << "x: " << x << "\n";
for (int i = 0; i < x; ++i)
std::cout << i+1 << "\n";
return 0;
}
我不能代表其他编译器,因为我只用 GNU C++ 编译器 4.9.2 版对此进行了测试。为什么允许这样的事情?这打破了 const
个对象的整个点。
我用g++编译了上面的代码main.c -Wall -Werror
输出:
*px: 11
x: 10
1
2
3
4
5
6
7
8
9
10
就编译器而言,您不是在修改常量。您正在修改指向非常量 int
的指针指向的内容,因为这就是强制转换 (int *)
告诉编译器将 &x
视为。
这种所谓的 C 风格转换是 C++ 提供的最强大的转换。铸造通常只应在真正必要的范围内进行。很多时候,const_cast
、static_cast
、dynamic_cast
就足够了(还有比较厉害的reinterpret_cast
)。
C 风格转换的行为是应用允许编译成功所需的最不强大的转换。