标签: void-pointers

void指针:C和C++之间的区别

我试图理解C和C++之间关于void指针的区别.以下编译用C而不是C++编译(所有编译都用gcc/g ++ -ansi -pedantic -Wall完成):

int* p = malloc(sizeof(int));
Run Code Online (Sandbox Code Playgroud)

因为malloc返回void*,C++不允许分配,int*而C允许.

但是,这里:

void foo(void* vptr)
{
}

int main()
{
    int* p = (int*) malloc(sizeof(int));
    foo(p);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

C++和C都编译它没有抱怨.为什么?

K&R2说:

任何指向对象的指针都可以转换为类型void *而不会丢失信息.如果结果转换回原始指针类型,则恢复原始指针.

这很好地总结void*了C中的转换.C++标准规定了什么?

c c++ void-pointers

18
推荐指数
2
解决办法
1万
查看次数

转换void指针

我在旧的C代码中看到了很多以下内容:

type_t *x = (type_t *) malloc(...);
Run Code Online (Sandbox Code Playgroud)

从那里malloc()开始返回指针的重点是什么void *?是因为较旧的C编译器不支持void指针而是malloc()习惯返回char *

c pointers void-pointers

17
推荐指数
2
解决办法
3万
查看次数

((void*) - 1)是一个有效的地址吗?

来自Linux的man shmat逐字:

返回值

返回错误(void*)-1,并设置errno以指示错误原因.

(POSIX使用略有不同的措辞来讲述相同的内容.)

是否有任何强制性规则或定义(标准?)(void *) -1可能不是有效地址?

c void-pointers

17
推荐指数
3
解决办法
3419
查看次数

什么时候uintptr_t优于intptr_t?

鉴于我需要在结构中存储"泛型"指针的值并且对指向的内存本身没有兴趣,我发现将它存储为intptr_t比a 更为语义正确void*.问题是a uintptr_t是否更适合,并且当一个人更喜欢另一个人时?

c pointers void-pointers

17
推荐指数
3
解决办法
6670
查看次数

C++,bool转换是否总是回退到隐式转换为void*?

问题:隐式bool转换是否总是回退到尝试隐式转换为void*?(如果存在类型的转换函数).如果是这样,为什么?

考虑以下简短程序:

#include <iostream>

class Foo{
public:

    operator void*() const
    {
        std::cout << "operator void*() const" << std::endl;
        return 0;
    }
};

int main()
{
    Foo f;

    if(f)
        std::cout << "True" << std::endl;
    else
        std::cout << "False" << std::endl;

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

该程序的输出是:

operator void*() const
False
Run Code Online (Sandbox Code Playgroud)

意思是,void*被称为转换函数.如果我们explicit在转换函数前面标记限定符,则隐式转换void*将失败.

编辑: 似乎很多答案是"空指针可以转换为false".我理解这一点,我的问题是关于"如果我不能直接调用operator bool()那么我将尝试转换为任何指针".

c++ void-pointers implicit-conversion

17
推荐指数
2
解决办法
1021
查看次数

对于所有类型,%p格式说明符都需要显式转换为void*,而printf中的char*

%p在Stack Overflow中已经阅读了很多关于C语言中格式说明符用法的答案,但似乎没有一个解释为什么void*所有类型都需要显式转换为char*.
我当然知道这样一个事实,即强制转换的要求void*与使用可变函数(参见本答案的第一条评论)有关,而非强制性要求.

这是一个例子:

int i;    
printf ("%p", &i);
Run Code Online (Sandbox Code Playgroud)

产生关于类型不兼容性的警告,并且&i应该进行铸造void*(根据标准的要求,再次参见此处).

虽然这一大块代码能够顺利编译,但没有关于类型转换的任何投诉:

char * m = "Hello";    
printf ("%p", m);
Run Code Online (Sandbox Code Playgroud)

如何char*从这一要求中"解脱"?

PS:可能值得补充的是我在 x86_64架构上工作,因为指针类型大小依赖于它,并且使用 gcc作为linux上的-W -Wall -std=c11 -pedantic编译器和编译选项.

c printf types casting void-pointers

17
推荐指数
3
解决办法
1157
查看次数

通用与类型安全?在C中使用void*

来自OO(C#,Java,Scala),我非常重视代码重用和类型安全的原则.上述语言中的类型参数可以完成这项工作并启用通用数据结构,这些结构既是类型安全的,也不会"浪费"代码.

当我陷入C时,我意识到我必须做出妥协,我希望它是正确的.我的数据结构void *在每个节点/元素中都有一个,我失去了类型安全性,或者我必须为我想要使用它们的每种类型重新编写我的结构和代码.

代码的复杂性是一个显而易见的因素:遍历数组或链接列表是微不足道的,并且添加*next一个结构不是额外的努力; 在这些情况下,不尝试重用结构和代码是有道理的.但对于更复杂的结构,答案并不那么明显.

还有模块化和可测试性:将类型及其操作与使用该结构的代码分离,使测试更容易.反之亦然:在一个结构上测试某些代码的迭代,同时它试图做其他事情变得混乱.

那么你的建议是什么?void *和重用或类型安全和重复的代码?有没有一般原则?当我不适合时,我是否试图强迫OO进行程序化?

编辑:请不要推荐C++,我的问题是关于C!

c generics void void-pointers

16
推荐指数
3
解决办法
5837
查看次数

如何在c中使用void*制作泛型函数?

我有一个incr函数来增加值1 我希望使它成为通用的,因为我不想为相同的功能创建不同的函数.

假设我要增加int,float,char1

void incr(void *vp)
{
        (*vp)++;
}
Run Code Online (Sandbox Code Playgroud)

但我知道的问题是Dereferencing a void pointer is undefined behaviour.有时可能会出错:Invalid use of void expression.

我的功能main是:

int main()
{

int i=5;
float f=5.6f;
char c='a';

incr(&i);
incr(&f);
incr(&c);

return 0;
}
Run Code Online (Sandbox Code Playgroud)

问题是如何解决这个问题?是否有解决这个问题的方式C只有

要么

我是否必须incr()为每种数据类型定义?如果是,那么有什么用呢void *

同样的问题swap()sort().我想交换和整理各种数据类型的功能相同的.

c void-pointers

16
推荐指数
3
解决办法
2万
查看次数

ISO C Void*和功能指针

在学习了一些教程并阅读有关函数指针的内容后,我了解到显然在ISO C中为函数指针指定了一个void指针是未定义的,有没有办法解决我在编译期间收到的警告(例如更好的编码方式)或我应该忽略它吗?

警告:

ISO C forbids assignment between function pointer and 'void *' [-pedantic]
Run Code Online (Sandbox Code Playgroud)

示例代码:

void *(*funcPtr)();
funcPtr = GetPointer();
Run Code Online (Sandbox Code Playgroud)

GetPointer是一个返回void指针EG的函数

void *GetPointer();
Run Code Online (Sandbox Code Playgroud)

c function-pointers void-pointers

16
推荐指数
3
解决办法
9688
查看次数

显式void指针作为函数参数

我有一个功能:

int foo(void * ptr)
{
   // ...
}
Run Code Online (Sandbox Code Playgroud)

我可以在C++ 11/14中语法上(不使用编译器警告等)禁用传递除void *自身以外的指针吗?

例如,现在它可以被称为:

foo(new int(42));
Run Code Online (Sandbox Code Playgroud)

我需要禁用它.

c++ void-pointers c++11 c++14

16
推荐指数
5
解决办法
1741
查看次数