rat*_*der 17 c c++ gcc pointers g++
在PJ Plauger的书"标准C库"中,他警告将函数指针赋给NULL.
具体来说,他说:
宏NULL 用作几乎通用的空指针常量.您将它用作数据对象指针的值,该指针应指向程序中未声明(或分配)的数据对象.正如我在第216页提到的,宏可以具有以下任何定义0,0L或(void*)0.
最后一个定义与任何数据对象指针兼容.但是,它与函数指针不兼容.这意味着你不能写
int (*pfun) (void) = NULL; /* WRONG */
翻译者可能会抱怨表达式类型与您要初始化的数据对象不兼容.
他继续说:
但是,无法保证指向void的指针与任何其他(非字符)指针具有相同的表示形式.它甚至不与函数指针兼容.这意味着您不能将NULL写为通用空指针常量.你也不能安全地将它用作参数表达式来代替任意数据对象指针.
我已经将函数指针分配NULL
了很长一段时间没有任何问题,我想知道它是否不可移植.
特别:
void (*test)() = NULL
=>用gcc和g ++编译好
void (*test)() = 0
=>用gcc和g ++编译好
void (*test)() = (void*)0
=>在gcc和g ++中都产生了无效的转换错误
编辑:void (*test)() = (void*)0
在gcc中编译很好,我使用的文件扩展名为.cpp ...尽管Plauger说分配函数指针NULL
是错误的,它仍然会编译吗?
我不明白的部分是我的stddef.h中NULL的定义:
#if defined (_STDDEF_H) || defined (__need_NULL)
#undef NULL /* in case <stdio.h> has defined it. */
#ifdef __GNUG__
#define NULL __null
#else /* G++ */
#ifndef __cplusplus
#define NULL ((void *)0) // this line confuses me
#else /* C++ */
#define NULL 0
#endif /* C++ */
#endif /* G++ */
#endif /* NULL not defined and <stddef.h> or need NULL. */
#undef __need_NULL
Run Code Online (Sandbox Code Playgroud)
这似乎NULL
在C++中定义为0,在C中定义为((void*)0).它是真的,还是被定义为__null?
编辑:如果是这样,为什么一直分配NULL
工作,即使根据Plauger分配给(void*)0,是"错误的"?
编辑2:我对C89感兴趣
小智 9
void (*test)() = (void*)0
=>在gcc和g ++中都产生了无效的转换错误
GCC根据文件扩展名检测语言..cc
使用GCC 编译文件将调用C++编译器,而不是 C编译器.
尝试使用C源文件,你会看到这是被接受的.应该是,因为它是标准所允许的.
如果是这样,为什么一直分配给NULL工作,但是不分配给(void*)0?
NULL
不允许((void*)0)
在C++模式下定义.在C++模式下,必须将其定义为值为0的整数常量,或者为nullptr
.可以转换为任何函数指针类型.
我能否始终在C和C++中可靠地将函数指针设置为NULL?
是的,在任何符合C或C++的实现中,这都可行.
int (*pfun) (void) = NULL;
Run Code Online (Sandbox Code Playgroud)
它实际上是有效的.
C的任务规则说:
(请注意,这是一个初始化,但适用与简单赋值相同类型的约束和转换.)
(C99,6.5.16.1简单赋值p1约束)"以下之一应保持:[...] - 左操作数是指针,右边是空指针常量;"
和
(C99,7.17p3)"宏是NULL,它扩展为实现定义的空指针常量;"
因此void *
,C允许为任何指针(对象指针,函数指针或)指定空指针常量.请注意,Plauger的书在提到标准C时引用了C89,但在C89中赋值约束的措辞是相同的.
归档时间: |
|
查看次数: |
9990 次 |
最近记录: |