【问题标题】:Why the statement int null = 0, *p = null is illegal?为什么声明 int null = 0, *p = null 是非法的?
【发布时间】:2016-01-02 01:17:59
【问题描述】:

我是 C++ 新手,正在尝试学习指针的概念。有人能告诉我为什么下面的 C++ 语句是非法的吗?在我看来是合法的,但有人告诉我这是非法的。

int null = 0, *p = null;

【问题讨论】:

    标签: c++ pointers c++11 nullptr


    【解决方案1】:

    C++ 标准允许将值0 作为常量分配给指针。

    但是,代码:

    int null = 0;
    int *p = null; 
    

    不会将p 设置为常量0,而是将其设置为null 的值,这是一个整数变量。

    如果我们稍微概括一下,将int null = 0; 放在一行中,将int *p = null; 放在完全不同的一行中,中间有一些代码。没有什么说两者之间的代码不做null = 4; - 但是,我不认为这是不允许这样做的主要原因,而是更容易编写一个检查“这是整数常量 0”而不是“这个命名常量是零值”。如果常量来自另一个编译单元(链接时常量)怎么办?

    此外,阅读0 比拥有 46 种不同的编码标准要容易得多,每种编码标准都为 null 使用不同的名称。

    请注意,即使您创建了const int null = 0;,它仍然不是常量0 - 它是一个与0 具有相同值的常量,但在词法上与0 不同。

    【讨论】:

    • 线程部分不是红鲱鱼吗?即使nullconstexpr,它仍然是非法的。
    • @Cornstalks:我不完全确定实际动机,但很明显,如果编译器确实允许非常量变体,那将是一个问题。当你写那条评论时,我只是在添加 const int null = 0;
    • 当然,我只是认为尝试使用线程作为理由通常是不正确的。编译器可以安全地假设 null 在语句 int *p = null; 中为 0。如果一个线程中断执行并将null 设置为某个值,则另一个线程继续执行并从null 读取将是未定义的行为(需要内存同步屏障)。
    • 好的,我已经重写了一点,这样它就不会谈论线程中断,而是更普遍的问题,如果你有int null = 0;,。不能保证null = 4; 或以后会发生类似情况...
    【解决方案2】:

    如果您尝试编译此代码,那么您应该得到以下错误:

    error: cannot initialize a variable of type 'int *' with an lvalue of type 'int'
    

    基本上发生的事情是您试图用变量初始化指针。 C++ 中唯一允许的是将指针直接分配给零。

    int * p = 0;
    

    上面的例子也可以。

    【讨论】:

      【解决方案3】:

      要定义一个指针,您需要使用 & 符号作为您要传递的对象的前缀。

      int null = 0, *p = &null;
      

      这将修复error: cannot initialize a variable of type 'int *' with an value of type 'int'

      【讨论】:

      • 这“修复”了错误,但改变了代码的含义。就像x#y 产生错误,但x+y 修复它。
      • 你显然不明白这行的用意。假设定义了 2 个整数类型;第一个名称为 null 的值为 0,第二个整数将从第一个的位置获取相同的值,名称为 p。
      • 不,第二个定义了一个指针p,初始化为null的,而不是null地址。跨度>
      • c++中定义空值的关键字是NULL或者nullptr...不是null。还有#号,我不确定它也代表什么。
      • C++ 中没有 NULL 关键字。从 C C++ 继承了一个macro NULL,但这一切在这里都无关紧要。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-12-09
      • 2019-11-06
      相关资源
      最近更新 更多