【问题标题】:Why MSVC14 allows declaring a pointer to a dynamic non-initialized const object?为什么 MSVC14 允许声明指向动态非初始化 const 对象的指针?
【发布时间】:2020-02-21 06:22:09
【问题描述】:

在“C++ Primer 5th edition”中,第 12 章“动态内存和智能指针”说:

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

所以这样的陈述被认为是错误的:

const int* pi = new const int;
  • 如果我在 GCC 上运行这个语句,它编译失败,但是为什么它在 MSVC14 上编译?

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

【问题讨论】:

  • 非标准编译器扩展。 (错误/功能)
  • MSVC 并不是最符合标准的编译器。
  • 从程序员的角度来看是愚蠢的?是的。从编译器的角度来看 - 不是那么多。只是另一个不合格的行为。 struct bar {}; new const bar; 编译得很好。
  • @HansPassant:我认为在您的示例中这是未定义的行为,因为使用 const_cast 抛弃了最初常量对象的常量性。
  • @HansPassant:但是 AFAIK 在指向 const 对象的指针上使用 const_cast 来更改这些对象是 UB。不是吗??!!!

标签: c++ dynamic-memory-allocation


【解决方案1】:

这不是 MSVC 中的“错误”,因为这不是编译器的工作,而是运行时的工作。

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];
    

为什么编译器允许使用超出范围的索引?再次因为编译器不知道那个运行时值;它只检查索引类型是否为可用于访问数组索引的相关类型。

【讨论】:

    猜你喜欢
    • 2020-05-28
    • 2017-01-05
    • 2015-12-31
    • 1970-01-01
    • 2017-11-20
    • 1970-01-01
    • 2012-04-19
    • 1970-01-01
    • 2014-09-08
    相关资源
    最近更新 更多