为什么MSVC14允许声明指向动态未初始化常量对象的指针

Why MSVC14 allows declaring a pointer to a dynamic non-initialized const object?

本文关键字:初始化 动态 常量 对象 指针 许声明 MSVC14 声明 为什么      更新时间:2023-10-16

在"C++初级读本第五版"中,第12章"动态内存和智能指针"中说:

与任何其他常量一样,必须初始化动态分配的常量对象。定义默认构造函数(§7.1.4,第263页(的类类型的const动态对象可以隐式初始化。其他类型的对象必须显式初始化。因为分配的对象是const,所以new返回的指针是指向const的指针(§2.4.2,第62页(。

所以这样的语句被认为是错误的:

const int* pi = new const int;
  • 如果我在GCC上运行此语句,它将无法编译,但为什么它要在MSVC14上编译?

  • 在我看来,这是一个愚蠢的错误,指针是指向const的指针,这意味着以后无法分配给它,访问它也是UB。

这不是MSVC中的"bug",因为这不是编译器的工作,而是运行时的工作。

const int ci; // error ci is a constant object in Stack-memory so it must be initialized at compile-time.

const int* cpi; // ok. just a pointer to const. The compiler doesn't know whether you'll assign an initialized const object or not.
int choice = 0;
std::cin >> choice;
if(choice == arbitraryValue)
cpi = new const int; // or cpi = new cont int(anotherArbitraryValue );
正如您所看到的,这是允许的,因为在编译时编译器不知道对象将如何在运行时创建和初始化。
  • 看起来你在问:

    int a[]{1, 2, 3, 4};
    int index;
    cin >> index; // e.g: user enters 10
    cout << a[i];
    
  • 为什么编译器允许使用超出范围的索引?同样,因为编译器不知道该运行时值;它只检查索引类型是否为可用于访问数组索引的相关类型。