相关疑难解决方法(0)

一致的C实现#define NULL可以是古怪的东西

我问,因为在这个帖子中引发了讨论.

尝试在其他人的回复下使用评论进行严肃的来回讨论并不容易或有趣.所以我想听听我们的C专家的想法,一次不限制500个字符.

C标准几乎没有什么可说的NULL和空指针常量.我只能找到两个相关部分.第一:

3.2.2.3指针

具有值0的整型常量表达式,或者类型为void*的表达式,称为空指针常量.如果为指针的相等性分配或比较空指针常量,则将常量转换为该类型的指针.这种称为空指针的指针保证与指向任何对象或函数的指针不相等.

第二个:

4.1.5通用定义

宏是

NULL
Run Code Online (Sandbox Code Playgroud)

它扩展为实现定义的空指针常量;

问题是,可以NULL扩展为实现定义的空指针常量,该常量与3.2.2.3中列举的那些不同吗?

特别是,它可以定义为:

#define NULL __builtin_magic_null_pointer
Run Code Online (Sandbox Code Playgroud)

甚至:

#define NULL ((void*)-1)
Run Code Online (Sandbox Code Playgroud)

我对3.2.2.3的解释是,它指定0的整数常量表达式和0强制转换为类型void*的整型常量表达式必须是实现可识别的空指针常量的形式,但它不是意思是一份详尽的清单.我相信实现可以自由地将其他源构造识别为空指针常量,只要没有其他规则被破坏.

例如,可以证明这一点

#define NULL (-1)
Run Code Online (Sandbox Code Playgroud)

不是法律定义,因为在

if (NULL) 
   do_stuff(); 
Run Code Online (Sandbox Code Playgroud)

do_stuff() 不能被称为,而与

if (-1)
   do_stuff();
Run Code Online (Sandbox Code Playgroud)

do_stuff()必须被召唤; 因为它们是等价的,所以这不是法律定义NULL.

但是标准说整数到指针的转换(反之亦然)是实现定义的,因此它可以定义-1到指针的转换,作为产生空指针的转换.在这种情况下

if ((void*)-1) 
Run Code Online (Sandbox Code Playgroud)

会评价为假,一切都会好的.

那么别人怎么想呢?

我要求每个人特别记住中描述的"假设"规则2.1.2.3 Program execution.它是巨大的,有点迂回,所以我不会在这里粘贴它,但它实质上说,一个实现只需要产生与标准描述的抽象机器所需的相同的可观察副作用.它表示,只要程序的可观察副作用不被它们改变,任何优化,转换或编译器想要对程序执行的任何其他操作都是完全合法的.

因此,如果您希望证明特定的定义NULL不合法,您需要提出一个可以证明它的程序.任何一个像我一样公然打破标准中的其他条款,或者可以合法地检测编译器必须做的任何魔法来使奇怪的NULL定义工作.

Steve Jessop发现了一个程序检测方法的例子,NULL它没有被定义为3.2.2.3中两种形式的空指针常量之一,它是将常量字符串化:

#define stringize_helper(x) #x
#define stringize(x) stringize_helper(x) 
Run Code Online (Sandbox Code Playgroud)

使用这个宏,人们可以

puts(stringize(NULL));
Run Code Online (Sandbox Code Playgroud)

并"检测"NULL不会扩展到3.2.2.3中的一个表单.这足以使其他定义非法吗?我只是不知道.

谢谢!

c null standards

26
推荐指数
2
解决办法
4429
查看次数

NULL保证为0吗?

我想知道是否NULL保证使用0C++,所以我搜索并发现了这些:


这个答案表明:

这是Bjarne Stroustrup的措辞,

在C++中,NULL的定义是0,因此只有美学差异.我更喜欢避免宏,所以我使用0. NULL的另一个问题是人们有时会错误地认为它与0不同和/或不是整数.

这似乎证实NULL总是0.


但根据cppreference.com:

#define NULL /*implementation-defined*/
Run Code Online (Sandbox Code Playgroud)

宏NULL是一个实现定义的空指针常量,可能是:

- >整数类型的整数常量表达式rvalue,其计算结果为零(直到C++ 11)

- >值为零的整数文字,或类型为std :: nullptr_t的prvalue(自C++ 11起)

这清楚地说NULL是依赖于实现.


这个答案说:

0(也称为C的NULL桥接到C++中)可能导致重载函数解析的模糊性,除其他外:

f(int); 
f(foo *);
Run Code Online (Sandbox Code Playgroud)

这再次暗示这NULL是整数0,可能会导致歧义


我遇到了其他问题和答案,但它们主要是关于C语言,而不是C++.这里的一个评论说:

并且NULL保证为0

但同样,这是关于C.


总而言之,NULL总是0在C++中?C怎么样?是(对于每个标准实现)是否相同:

#define NULL 0
Run Code Online (Sandbox Code Playgroud)

注意:这个问题与空指针无关,问题是NULL在C++中是否保证是0整数.它是依赖于实现的吗?

c++ null

7
推荐指数
1
解决办法
491
查看次数

为什么不允许指针+指针但允许指针+整数?

我正在通过C指针算术.我发现不允许添加指针但pointer + integer允许.

pointer + pointer由于安全原因,我认为是不允许的.但是,如果一个指针p1持有66400p2持有,该怎么办66444?现在p1+p2是不被允许但是p1+66444被允许.为什么这样?

c c++ pointers

-1
推荐指数
1
解决办法
278
查看次数

标签 统计

c ×2

c++ ×2

null ×2

pointers ×1

standards ×1