C语言中NULL的误解。。。
c语言吧
全部回复
仅看楼主
level 11
pengzhenxx 楼主
C语言中NULL,就是个概念本身并没有什么,其定义为宏: #define NULL ((void*)0)。。。很多人会产生误解,以为NULL就是0,其实完全可以自己定义NULL,你定义为1或者其他任何整数(不于系统地址冲突)都行,NULL只是个空的概念,,,所以大家在进行控制指针判断时,不要写 !p 之类的判断语句,一定要老老实实的写 p == NULL
2020年02月28日 14点02分 1
吧务
level 14
C标准规定NULL的定义只能是两种:0或者(void*)0。你把NULL重定义为1,那就是你违反了标准。使用!p判断指针非空完全符合标准。
2020年02月28日 14点02分 2
其它我都同意,但关于 NULL 的定义,我觉得只要合理即可,因为标准说的是实现定义。
2020年02月28日 14点02分
@aaaaaaa421 关于NULL:The macros are NULL which expands to an implementation-defifined null pointer constant
2020年02月28日 14点02分
@aaaaaaa421 关于null pointer constant:An integer constant expression with the value 0, or such an expression cast to typevoid *, is called a null pointer constant.
2020年02月28日 14点02分
@aaaaaaa421 所以理论上是的,应该是所有求值得到0或者(void*)0的整型常量表达式都可以作为NULL的定义。理论上#define NULL (1+1-2)也是符合标准的。但是#define NULL ((void*)1)是一定不符合标准的。
2020年02月28日 14点02分
level 3
多谢楼主开贴拓展这个概念[真棒]。但是#define NULL ((void*)0)里面的((void*)0)看不懂[吐舌]
2020年02月28日 14点02分 3
还要多亏你的题目,我以前也没有注意这个问题。。。。(viod*)只是强转为void类型的指针
2020年02月29日 02点02分
void*可以表示任何类型的指针,0是地址,一般是非法地址
2020年02月29日 05点02分
@fx2422esplus 刚想问这个0是啥,涨知识了,谢谢
2020年02月29日 05点02分
level 15
如果只是 C 就算了,但放在更一般的背景下这种习惯是个错误示范。
最直接的理由是,因为很多 C 代码同时会被当作 C++ 代码复用(通过预处理器控制),而在 C++ 下,这里的惯用法就有些问题了。
C++ 中,像 if 这样的上下文专门引入 contextually convert to bool 来描述,这是一个语言层面上一等的机制,独立于整数表示的含义的判断。虽然这个 wording 是 C++11 加入的,根本问题是 C++ 原生支持具有特定用途的 bool ,而不是 C99 这样加补丁搞的 _Bool ,并没法让 if 依赖。虽然 C++ 这样做的必要性还有跟 explicit 之类搞事的问题,但
原则上 C 缺乏 bool 而让整数越俎代庖开洞是个过时的设计,据此不得不依赖 == 来判断条件,在有其它选择的情形下也不是一个好习惯。
使用 NULL 至少对兼容 C++ 的代码还有其它显然的问题,例如 -Wzero-as-null-pointer-constant 。这种情况下就算非要用显式的空指针,也应该用字面量 nullptr 而不是 NULL 。注意 C++ 虽然一直支持 NULL ,但一直以来都和 C 略有区别——允许是 0 或者 0L 而禁止(void*)0 。这个限制和类型检查的强度有关(考虑 char* p = NULL; ),再次暴露了 C 设计在这里的无能(虽然讽刺的是,C++ 引入 nullptr 的一个原因是 0 或 0L 的类型干扰重载)。
2020年02月29日 03点02分 5
level 15
依赖整数类型 bool 的习惯在工业界还有一些更加作死的例子。可能很多人会遇到的,Win32 的 BOOL 导致莫名其妙的“性能警告”,需要显式转换或者比较判断来解决。从错误的源头来讲,引入比较在逻辑上也是说不通的。
这种流毒还会在莫名其妙的地方生效。一个很多人大概都不知道的例子是,CLR 底层的 bool 实际上类似伪劣的 BOOL ,而 C# 这种真正的 bool 的语言因为支持互操作,结果会引起在 bool 外能表示的值……这种情况在 C++ 直接是未定义行为,但在 C# 就强行是文档 bug 了,即便 C# 的 spec 根本没打算允许在 safe 代码中出现这种实质上的未定义行为(Roslyn 大概就是实现开洞处理,等效当作未定义行为)。
2020年02月29日 03点02分 6
level 11
pengzhenxx 楼主
谈严格的C语言标准的没有多大意义,,,C语言没有将NULL在语法上实现,也没有在语法上实现BOOL,就是为了让编程更加灵活,,,
比如我的一个项目,为了统一性(大型项目统一性十分重要,当然我举的这个例子很极端),我将0做其他作用,并不代表就是BOOL的假,或者NULL,我就要重新定义BOOL的FALSE,TRUE和NULL,如果C语言在语法上写死,反而就不能这么灵活了
2020年02月29日 03点02分 7
level 11
pengzhenxx 楼主
很多时候感觉这就也是C语言故意不写死,就是要让用户自己去定义,自己去扩展的。。。毕竟在语法上强制写死NULL,BOOLEAN等等是很容易的事情。。。。毕竟就算是不少库中,NULL的定义也是类似这样写的
#ifndef NULL
#define NULL ((void *)0)
#endif
2020年02月29日 04点02分 9
level 13
你要非得重新define一下从语法上讲也没毛病 从行为上说你是小项目坑自己大项目坑队友 专坑自己人系列 你信不信当你队友发现你对Null重新定义后 他手边就会放把菜刀?!
2020年02月29日 04点02分 10
项目有项目说明,且有严格的统一性要求,如果一个人来加入项目,没有仔细阅读项目说明,它写的代码就是坑项目。。。。我上面举了例子,虽然很极端,但是是被允许的,我的项目0就是其他作用,不用做NULL和FALSE,这是会在项目说明中明确写好的
2020年02月29日 04点02分
@pengzhenxx …… 牛啤 见过各种项目文档 但第一次听说有项目说明这个东西 而且第一次听说还有这样用途的项目说明 我孤陋寡闻了
2020年02月29日 04点02分
@宇文nick 我说了,我举的例子很极端,但是是被允许的
2020年02月29日 04点02分
@pengzhenxx 我也说了语法上没毛病啊 但是我想绝大部分项目管理者在新人进入团队的时候都不会记得交代一句:你们千万记得不要redefine NULL啊
2020年02月29日 04点02分
1