我在一本书中看到了 excersise ,但我无法找到答案:
以下代码是否合法?如果没有,你怎么能做到 法律?
int null = 0, *p = null;
当然,第二个不合法,你不能将int转换为int *。
主题位于constexpr
。
GUYS!这只是一个关于指针,consts和constexprs的练习!我想,你必须在没有强制转换和nullptr的情况下解决它。
答案 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*>
以使其有效。