如何在C ++中使这个初始化合法化?

时间:2016-11-24 13:07:59

标签: c++ c++11

我在一本书中看到了 excersise ,但我无法找到答案:

  

以下代码是否合法?如果没有,你怎么能做到   法律?

     

int null = 0, *p = null;

当然,第二个不合法,你不能将int转换为int *。

主题位于constexpr

部分

GUYS!这只是一个关于指针,consts和constexprs的练习!我想,你必须在没有强制转换和nullptr的情况下解决它。

6 个答案:

答案 0 :(得分:9)

在C ++ 11中,空指针常量定义为

  

整数类型的整数常量表达式prvalue,其计算结果为零

(C ++ 11 [conv.ptr] 4.10 / 1)

这意味着在声明中添加constexpr实际上使null有效的空指针不变:

constexpr int null = 0, *p = null;

请注意,这被认为是一个缺陷并在C ++ 14中发生了变化,因此只有整数 literal 才能成为空指针常量:

  

空指针常量是一个整数字面值,其值为零...

(C ++ 14 N4140 [conv.ptr] 4.10 / 1)

因此,有一种方法可以在C ++ 11中使用constexpr使初始化合法化,但它的存在被认为是标准缺陷并在C ++ 14中被删除。因此,这本书教授过时的信息。

请注意,因为这是一个缺陷,编译器通常也会将此行为反向移植到他们的C ++ 11模式(如果他们甚至首先实现了原始行为)。

答案 1 :(得分:3)

另一个答案错过了一个非常简单的解决方案,使其合法化:让null成为指针:

int *null = 0, *p = null;

但如上所述,最佳解决方案是根本不使用null变量,而是使用标准nullptr

答案 2 :(得分:2)

如果你想要最小的差异,你可以选择

int null = 0, *p = nullptr;
                       ^^^

int null = 0, *p = {};

int null = 0, *p = 0;

最后一个例子可能令你感到惊讶,但它的定义方式(在C ++ 14中)要求整数字面值为零。不是类型为int的对象。

或者,如果您不缩进以对p进行零初始化,则可以使用null的地址对其进行初始化:

int null = 0, *p = &null;

答案 3 :(得分:1)

您可以选择几种方式使其合法化,仅举几例:

int null = 0, *p = 0;

int null = 0, *p = nullptr;

答案 4 :(得分:1)

确实这不合法:

int null = 0, *p = null;

以及:

int null = 0, *p = static_cast<int*>(null);

这些编译,等同于:

int null = 0, *p = (int*)null;
int null = 0, *p = reinterpret_cast<int*>(null);

但应该避免,如here所述。

C风格的演员(int*)null在C ++中被认为是一种不好的做法(很明显,这部分是一个观点问题),主要是因为很难用自己的眼睛看代码(对于强制转换通常没有语法高亮显示)或者使用搜索/查找命令(如何将强制转换与其他类型用法分开,例如变量声明?)。

reinterpret_cast更加明显,可以轻松搜索,但与C风格的演员一样宽容,所以除非你确切知道为什么要使用它,否则应该避免使用它。

当然,C ++ 11中的良好初始化将是:

int null = 0, *p = nullptr;

答案 5 :(得分:-1)

我认为您可以在int上使用reinterpret_cast<int*>以使其有效。