64位系统上的NULL定义问题 [英] NULL definition problem on 64 bit system
问题描述
我有一个效用函数:
$ b我使用gcc 4.1.2在RHEL 5.1 64位平台上运行。 $ b
void str_concat(char * buff,int buffSize,...);
其中conc char char *在可变参数列表(...)中传递,而最后一个参数应该为NULL,指定参数的结尾。在64位系统上,NULL是8个字节。
现在解决问题。我的应用程序包含直接/间接2个stddef.h文件。
第一个是 /usr/include/linux/stddef.h ,它定义了NULL如下所示:
#undef NULL
#if defined(__ cplusplus)
#define NULL 0
$#$
#define NULL((void *)0)
#endif
第二个是 /usr/lib/gcc/x86_64-redhat-linux/4.1.2/include/stddef.h
#if defined(_STDDEF_H)|| defined(__need_NULL)
#undef NULL / *在< stdio.h>已经定义了它。 * /
#ifdef __GNUG__
#define NULL __null
#else / * G ++ * /
#ifndef __cplusplus
#define NULL((void *)0)
#else / * C ++ * /
#define NULL 0
#endif / * C ++ * /
#endif / * G ++ * /
#endif / * NULL not定义和< stddef.h>或者需要NULL。 * /
#undef __need_NULL
当然,我需要第二个,因为它定义了NULL作为__null(8字节),而第一个将其定义为整数0(4字节)。
如何防止/usr/include/linux/stddef.h被错误地包含?
UPD :
-
编辑线非常简单:
g ++ -Wall -fmessage-length = 0 -g -pthread
-
许多人建议通过(void *)0。这当然会起作用。这个函数在很多地方使用的问题,我的意思是很多地方。我希望找到能给我C ++标准承诺的解决方案 - 8字节大小的NULL。
解决方案
在这种情况下,没有NULL定义问题。您在代码中如何使用 NULL
存在问题。
NULL
不能自行传递给C / C ++中的可变参数函数。你必须在传递之前明确地转换它,也就是说,你必须传递(const char *)NULL
作为参数列表的终止符。
你的问题被标记为C ++。在任何情况下,无论大小如何,在C ++ NULL
中总会被定义为一个整数常量。在C ++中定义 NULL
作为指针是非法的。因为你的函数需要一个指针( const char *
),所以在C ++代码中没有定义 NULL
。
对于更干净的代码,您可以定义自己的常量,如
const char * const STR_TERM = NULL;
并用于调用函数。但是你永远不能仅仅为了这个目的而使用 NULL
。无论何时传递一个简单的 NULL
作为可变参数,它都是一个明显的可移植性错误,必须修正。
增加:您的更新声称C ++标准承诺<8位字节大小的code> NULL(在我假设的64位平台上)。这只是没有任何意义。 C ++标准不承诺任何类似于 NULL
的东西。
NULL
旨在用作右值。它没有特定的大小,并且没有有效的使用 NULL
,其实际大小甚至可能是远程问题。
引用ISO / IEC 14882:1998第18.1节类型第4段:
宏NULL是一个实现定义的
C ++空指针常量,在这个国际标准
(4.10)。180)
180)可能的定义包括0和0L,但不包括(void *)0。
I'm running on RHEL 5.1 64 bit platfrom using gcc 4.1.2.
I have a utility function:
void str_concat(char *buff, int buffSize, ...);
which concats char * passed in variadic list(...), while last argument should be NULL, to designate end of the arguments. On 64 bit system NULL is 8 bytes.
Now to the problem. My application includes directly/indirectly 2 stddef.h files.
First one is /usr/include/linux/stddef.h which defines NULL as following:
#undef NULL
#if defined(__cplusplus)
#define NULL 0
#else
#define NULL ((void *)0)
#endif
The second one is /usr/lib/gcc/x86_64-redhat-linux/4.1.2/include/stddef.h
#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)
#else /* C++ */
#define NULL 0
#endif /* C++ */
#endif /* G++ */
#endif /* NULL not defined and <stddef.h> or need NULL. */
#undef __need_NULL
Of course I need the 2nd one, since it defines NULL as __null (8 bytes), while 1st one defines it as integer 0 (4 bytes).
How do I prevent /usr/include/linux/stddef.h to be inderectly included?
UPD:
Compilation line is pretty straightforward:
g++ -Wall -fmessage-length=0 -g -pthread
Many of you advised to pass (void *)0. This of course will work. The problem that the function is used in many, I mean many places. I'd like to find solution that will give me what C++ standard promises - NULL of 8 byte size.
There's no "NULL definiton problem" in this case. There's a problem with how you are trying to use NULL
in your code.
NULL
cannot be portably passed to variadic functions in C/C++ by itself. You have to explicitly cast it before passing, i.e. in your case you have to pass (const char*) NULL
as the terminator of the argument list.
Your question is tagged as C++. In any case, regardless of size, in C++ NULL
will always be defined as an integer constant. It is illegal in C++ to define NULL
as a pointer. Since your function expects a pointer (const char *
), no definition of NULL
will ever work for it in C++ code.
For cleaner code you can define your own constant, like
const char* const STR_TERM = NULL;
and use it in the calls to your function. But you will never be able to meaningfully use just NULL
for that purpose. Whenever a plain NULL
is passed as a variadic argument, it is a blatant portability bug that has to be fixed.
Added: your update claims that "C++ standard promises NULL
of 8 byte size" (on a 64-bit platform I presume). This just doesn't make any sense. C++ standard does not promise anything like that about NULL
.
NULL
is intended to be used as an rvalue. It has no specific size and there's no valid use of NULL
where its actual size might even remotely matter.
Quoting from ISO/IEC 14882:1998, section 18.1 'Types', paragraph 4:
The macro NULL is an implementation defined C++ null pointer constant in this International Standard (4.10).180)
180) Possible definitions include 0 and 0L, but not (void*)0.
这篇关于64位系统上的NULL定义问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!