在C中使用void *指针的缺点

时间:2022-09-06 19:20:58

There are many drawbacks to using void * in C (memory related, type related, efficiency wise ...). In spite of them we use them a lot for the flexibility they provide.

在C中使用void *有许多缺点(与内存相关,类型相关,效率明智......)。尽管如此,我们还是使用它们来提供灵活性。

List the disadvantages/drawbacks using void * (and preferred solution in C - if possible).

列出使用void *(和C中的首选解决方案 - 如果可能的话)的缺点/缺点。

EDIT: please go through the follwoing link: http://attractivechaos.wordpress.com/2008/10/02/using-void-in-generic-c-programming-may-be-inefficient/

编辑:请通过以下链接:http://attractivechaos.wordpress.com/2008/10/02/using-void-in-generic-c-programming-may-be-inefficient/

6 个解决方案

#1


14  

There are no efficiency issues with void pointers. The only limitations with void pointers are:

void指针没有效率问题。 void指针的唯一限制是:

  • you cannot dereference void pointer for obvious reasons
  • 出于显而易见的原因,你无法取消引用void指针

  • sizeof(void) is illegal
  • sizeof(void)是非法的

  • you cannot perform pointer arithmetics on void pointers
  • 你无法在void指针上执行指针算术

However GCC assumes that sizeof(void) is 1 and allows pointer arithmetics on void pointers - see here

但是GCC假设sizeof(void)是1并允许指针算术在void指针上 - 见这里

#2


14  

I disagree with the premise of the question. We use void* in C because it's the only way to get polymorphism. Example: library functions qsort and bsearch. There is only one drawback, which is that polymorphism based on void * is unsafe: once you cast a pointer to void *, there is nothing that prevents you from casting that void * to the wrong pointer type by mistake. My students make this mistake often.

我不同意这个问题的前提。我们在C中使用void *,因为它是获得多态的唯一方法。示例:库函数qsort和bsearch。只有一个缺点,即基于void *的多态性是不安全的:一旦你将指针强制转换为void *,就没有什么可以阻止你错误地将那个void *转换为错误的指针类型。我的学生经常犯这个错误。

There can be an efficiency cost because it is sometimes necessary to allocate heap space in order to use a polymorphic data structure.

可能存在效率成本,因为有时需要分配堆空间以使用多态数据结构。

Anybody who wants to see the advantages and tradeoffs in using polymorphic data structures with void * should get a copy of Dave Hanson's book C Interfaces and Implementations

任何想要看到使用void *的多态数据结构的优点和权衡的人都应该得到Dave Hanson的书C接口和实现的副本

#3


3  

Uh ... I'm not sure there are that many. Of course, you should never use void* when you don't have to. If there is a well-defined type you can use, then do that.

呃......我不确定那么多。当然,你不应该使用void *。如果您可以使用明确定义的类型,那么就这样做。

In my experience, void* is best for "anonymous" pointers (what a shock!), as in malloc()'s return value, and when just dealing with opaque buffers of bits. Oftentimes, you want to address those buffers at e.g. the byte level, and then you'd use unsigned char *, of course.

根据我的经验,void *最适合“匿名”指针(多么令人震惊!),如malloc()的返回值,以及处理不透明的位缓冲区时。通常情况下,您希望在例如:字节级别,然后你使用unsigned char *,当然。

Just randomly using void* wherever you need a pointer would be just broken, smelly code, and to be avoided of course.

只需随机使用void *,只要你需要一个指针,就会破坏,发臭的代码,当然要避免使用。

#4


2  

The linked-to post compares operations with void pointers to operations with C++ templates, and concludes that the templates are more efficient. This is hardly a surprise, and the C++ code I've seen uses void pointers rarely or never. It generally offers no advantage over other C++ facilities, and can be a gaping hole in the type system.

链接到帖子将操作与使用C ++模板的操作的void指针进行比较,并得出结论模板更有效。这并不奇怪,我见过的C ++代码很少或从不使用void指针。它通常没有其他C ++设施提供优势,并且可能是类型系统中的一个漏洞。

However, C does not have C++-style templates, and void pointers are necessary to implement functionality that has to be independent of data type.

但是,C没有C ++样式的模板,并且void指针是实现必须独立于数据类型的功能所必需的。

Therefore, when you're writing in C, and you need genericity, void pointers are the most efficient means of getting it (since they're the only means). When you're writing in C++, there's better ways to do almost anything void pointers can accomplish, so don't use them.

因此,当你用C语言编写,并且需要通用性时,void指针是获得它的最有效方法(因为它们是唯一的手段)。当你用C ++编写时,有更好的方法可以完成虚拟指针可以完成的任何操作,所以不要使用它们。

#5


1  

Your given link, is partially true. Especially, when you are not dealing with objects (structs), or in general with types that aren't already allocated. Using native types like ints, doubles etc. and void-pointers (e.g. for a container) is nearly always an icky affair, because you have either the choice to cast the int (for a double this doesn't work) to a pointer or you need to allocate extra memory for the data type.

您给出的链接部分属实。特别是,当您不处理对象(结构)时,或者通常使用尚未分配的类型时。使用像int,double等原生类型和void指针(例如对于容器)几乎总是一个蠢事,因为你有选择将int(对于一个double,这不起作用)转换为指针或者您需要为数据类型分配额外的内存。

First choice is bad because it is not portable, 0s are maybe not allowed as a value and it simply feels bad. Second choice wastes memory and is indeed a (massive) slow down because of the extra allocations.

首选是不好的,因为它不可移植,0可能不允许作为一个值,它只是感觉不好。第二种选择会浪费内存,而且由于额外的分配,确实会导致(大规模)减速。

But in most cases you aren't dealing with native types, but with objects, better said with pointers to objects, which are already allocated, at least I do. I never needed a hash-table or a map for integers or doubles. And having different container implementations only for type safeness of pointers feels wrong to me, because every implementation will increase your binary size. So if you are only need a container to store your pointers, there is no slow down or memory waste in using void-pointers.

但在大多数情况下,你不是处理本机类型,而是使用对象,最好用指向已经分配的对象的指针来表示,至少我这样做。我从来不需要哈希表或整数或双打的地图。并且仅针对指针的类型安全性而使用不同的容器实现对我来说是错误的,因为每个实现都会增加您的二进制大小。因此,如果您只需要一个容器来存储指针,那么使用void指针不会减慢速度或浪费内存。

But note, this was all about container implementations, like btw the blog article you mentioned. In general there are many things you cannot accomplish without using void-pointers.

但请注意,这完全是关于容器实现的,就像你提到的博客文章一样。一般来说,如果不使用void-pointers,有很多事情是无法完成的。

#6


1  

I dunno, I have found void pointers to be pretty effective for accessing different levels of abstraction (ABCs). As a means of navigating interlinked classes at different levels of abstraction. Its so simple, its awesome. Like the formula for e or the golden ratio, there should be an occult that worships the void* its that great :)

我不知道,我发现无效指针对于访问不同级别的抽象(ABC)非常有效。作为在不同抽象层次上导航相互关联的类的一种手段。它如此简单,令人敬畏。就像e或黄金比例的公式一样,应该有一个神秘的崇拜空虚*它那伟大的:)

#1


14  

There are no efficiency issues with void pointers. The only limitations with void pointers are:

void指针没有效率问题。 void指针的唯一限制是:

  • you cannot dereference void pointer for obvious reasons
  • 出于显而易见的原因,你无法取消引用void指针

  • sizeof(void) is illegal
  • sizeof(void)是非法的

  • you cannot perform pointer arithmetics on void pointers
  • 你无法在void指针上执行指针算术

However GCC assumes that sizeof(void) is 1 and allows pointer arithmetics on void pointers - see here

但是GCC假设sizeof(void)是1并允许指针算术在void指针上 - 见这里

#2


14  

I disagree with the premise of the question. We use void* in C because it's the only way to get polymorphism. Example: library functions qsort and bsearch. There is only one drawback, which is that polymorphism based on void * is unsafe: once you cast a pointer to void *, there is nothing that prevents you from casting that void * to the wrong pointer type by mistake. My students make this mistake often.

我不同意这个问题的前提。我们在C中使用void *,因为它是获得多态的唯一方法。示例:库函数qsort和bsearch。只有一个缺点,即基于void *的多态性是不安全的:一旦你将指针强制转换为void *,就没有什么可以阻止你错误地将那个void *转换为错误的指针类型。我的学生经常犯这个错误。

There can be an efficiency cost because it is sometimes necessary to allocate heap space in order to use a polymorphic data structure.

可能存在效率成本,因为有时需要分配堆空间以使用多态数据结构。

Anybody who wants to see the advantages and tradeoffs in using polymorphic data structures with void * should get a copy of Dave Hanson's book C Interfaces and Implementations

任何想要看到使用void *的多态数据结构的优点和权衡的人都应该得到Dave Hanson的书C接口和实现的副本

#3


3  

Uh ... I'm not sure there are that many. Of course, you should never use void* when you don't have to. If there is a well-defined type you can use, then do that.

呃......我不确定那么多。当然,你不应该使用void *。如果您可以使用明确定义的类型,那么就这样做。

In my experience, void* is best for "anonymous" pointers (what a shock!), as in malloc()'s return value, and when just dealing with opaque buffers of bits. Oftentimes, you want to address those buffers at e.g. the byte level, and then you'd use unsigned char *, of course.

根据我的经验,void *最适合“匿名”指针(多么令人震惊!),如malloc()的返回值,以及处理不透明的位缓冲区时。通常情况下,您希望在例如:字节级别,然后你使用unsigned char *,当然。

Just randomly using void* wherever you need a pointer would be just broken, smelly code, and to be avoided of course.

只需随机使用void *,只要你需要一个指针,就会破坏,发臭的代码,当然要避免使用。

#4


2  

The linked-to post compares operations with void pointers to operations with C++ templates, and concludes that the templates are more efficient. This is hardly a surprise, and the C++ code I've seen uses void pointers rarely or never. It generally offers no advantage over other C++ facilities, and can be a gaping hole in the type system.

链接到帖子将操作与使用C ++模板的操作的void指针进行比较,并得出结论模板更有效。这并不奇怪,我见过的C ++代码很少或从不使用void指针。它通常没有其他C ++设施提供优势,并且可能是类型系统中的一个漏洞。

However, C does not have C++-style templates, and void pointers are necessary to implement functionality that has to be independent of data type.

但是,C没有C ++样式的模板,并且void指针是实现必须独立于数据类型的功能所必需的。

Therefore, when you're writing in C, and you need genericity, void pointers are the most efficient means of getting it (since they're the only means). When you're writing in C++, there's better ways to do almost anything void pointers can accomplish, so don't use them.

因此,当你用C语言编写,并且需要通用性时,void指针是获得它的最有效方法(因为它们是唯一的手段)。当你用C ++编写时,有更好的方法可以完成虚拟指针可以完成的任何操作,所以不要使用它们。

#5


1  

Your given link, is partially true. Especially, when you are not dealing with objects (structs), or in general with types that aren't already allocated. Using native types like ints, doubles etc. and void-pointers (e.g. for a container) is nearly always an icky affair, because you have either the choice to cast the int (for a double this doesn't work) to a pointer or you need to allocate extra memory for the data type.

您给出的链接部分属实。特别是,当您不处理对象(结构)时,或者通常使用尚未分配的类型时。使用像int,double等原生类型和void指针(例如对于容器)几乎总是一个蠢事,因为你有选择将int(对于一个double,这不起作用)转换为指针或者您需要为数据类型分配额外的内存。

First choice is bad because it is not portable, 0s are maybe not allowed as a value and it simply feels bad. Second choice wastes memory and is indeed a (massive) slow down because of the extra allocations.

首选是不好的,因为它不可移植,0可能不允许作为一个值,它只是感觉不好。第二种选择会浪费内存,而且由于额外的分配,确实会导致(大规模)减速。

But in most cases you aren't dealing with native types, but with objects, better said with pointers to objects, which are already allocated, at least I do. I never needed a hash-table or a map for integers or doubles. And having different container implementations only for type safeness of pointers feels wrong to me, because every implementation will increase your binary size. So if you are only need a container to store your pointers, there is no slow down or memory waste in using void-pointers.

但在大多数情况下,你不是处理本机类型,而是使用对象,最好用指向已经分配的对象的指针来表示,至少我这样做。我从来不需要哈希表或整数或双打的地图。并且仅针对指针的类型安全性而使用不同的容器实现对我来说是错误的,因为每个实现都会增加您的二进制大小。因此,如果您只需要一个容器来存储指针,那么使用void指针不会减慢速度或浪费内存。

But note, this was all about container implementations, like btw the blog article you mentioned. In general there are many things you cannot accomplish without using void-pointers.

但请注意,这完全是关于容器实现的,就像你提到的博客文章一样。一般来说,如果不使用void-pointers,有很多事情是无法完成的。

#6


1  

I dunno, I have found void pointers to be pretty effective for accessing different levels of abstraction (ABCs). As a means of navigating interlinked classes at different levels of abstraction. Its so simple, its awesome. Like the formula for e or the golden ratio, there should be an occult that worships the void* its that great :)

我不知道,我发现无效指针对于访问不同级别的抽象(ABC)非常有效。作为在不同抽象层次上导航相互关联的类的一种手段。它如此简单,令人敬畏。就像e或黄金比例的公式一样,应该有一个神秘的崇拜空虚*它那伟大的:)