64位系统上的NULL定义问题 [英] NULL definition problem on 64 bit system

查看:183
本文介绍了64位系统上的NULL定义问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



我有一个效用函数:
$ 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 :


  1. 编辑线非常简单:

    g ++ -Wall -fmessage-length = 0 -g -pthread


  2. 许多人建议通过(void *)0。这当然会起作用。这个函数在很多地方使用的问题,我的意思是很多地方。我希望找到能给我C ++标准承诺的解决方案 - 8字节大小的NULL。

  3. 解决方案

在这种情况下,没有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:

  1. Compilation line is pretty straightforward:

    g++ -Wall -fmessage-length=0 -g -pthread

  2. 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆