【问题标题】:In C,is casting to (void*) not needed/inadvisable for memcpy() just as it is not needed for malloc()?在 C 中,对于 memcpy() 是否不需要/不建议转换为 (void*),就像 malloc() 不需要它一样?
【发布时间】:2013-05-08 05:30:11
【问题描述】:

我对从以下网站读到的关于memcpy()(和malloc())的内容有些困惑:

http://www.cplusplus.com/reference/cstring/memcpy/

在该页面中,明确说明了以下两行:

目的地

Pointer to the destination array where the content is to be copied, type-casted to a pointer of type void*.

来源

Pointer to the source of data to be copied, type-casted to a pointer of type const void*.

但紧接着,在代码中,在使用memcpy() 的以下两行中没有转换为void*

    memcpy ( person.name, myname, strlen(myname)+1 );
    memcpy ( &person_copy, &person, sizeof(person) );

请回答由这个前提引起的以下两个问题:

1) 在 C 的情况下(相对于 C++)是否可以并且建议不要将返回类型或 @987654331 中的参数转换为 void* @ 就像在 C 中不要将 malloc() 的返回类型转换为 void*建议 没关系?如果是这样,我直觉地觉得,为什么在那个著名的网站上明确说明我们需要将其转换为void*(即使它没有在代码中使用它)。那个网站有错吗?

2) 现在关于那个知名网站的真正矛盾。考虑以下

http://www.cplusplus.com/reference/cstdlib/malloc/

malloc()的情况下,在描述中,写成optional来强制转换为void*返回类型(确切的词“..can be cast to the desired type..”),不像在上面memcpy() 的情况据说将被转换为void*。但是在memcpy() 中,即使写入it is to be cast,转换也没有完成,在malloc() 的情况下,尽管它是写成can be cast to void*,但已完成对void* 的转换。现在我发现对于C 我们不应该转换@987654346 @返回void*

再次简而言之,以免回答的人在我冗长的描述中感到困惑:

--C 中是否建议不要将void* 的返回值和参数转换为memcpy()

--该站点是否对 malloc() 有误,因为它在 C 代码中将 malloc() 返回到 void*

【问题讨论】:

  • mallocmemcpy 在 C++ 中只存在边际,主要是为了与 C 兼容。C++ 有不同的构造更适合它们的类型系统。所以最好不要将 C++ 站点作为 C 的参考。它只是不同。
  • @JensGustedt 有一次我想到了,但是当我看到程序本身是 C 时,我以为是在谈论 C 的情况
  • @JensGustedt C standard library 部分中的所有程序都在 C 中。
  • memcpy的函数签名可以看出他们提供的不是C站点。 C中的签名不同,它有restrict,C++中不存在。
  • @JensGustedt 感谢您的洞察力。

标签: c casting malloc void-pointers memcpy


【解决方案1】:

来自 C 语言规范的 ISO/IEC 9899:2011,第 6.3.2.3 节,第 55 页:

指向void 的指针可以转换为或从指向任何对象类型的指针转​​换。指向任何对象类型的指针可以转换为指向void 的指针并再次返回;结果应与原始指针比较。

所以你基本上不需要将void* 的结果转换为所需的类型,也不需要做相反的事情。

【讨论】:

  • 我不太明白。你能在我的问题中更详细地解释一下吗。你的回答就像all meat,but tough to chew。你能不能让它变得不那么密集,请问有详细的吗?
  • 就像为什么要为 malloc() 而不是 memcpy() 进行转换,即使它声明 要为 memcpy() 转换,但对于 @987654328 是可选的@?
  • 没有详细信息。在 C 中,void* 可以在不需要强制转换的情况下与任何其他指针 odany 不同类型相互转换,sic et simpliciter。忘记在那个特定网站上写的内容,在你的情况下,演员表在语法上都是正确的,但没有必要。
  • Cast 对于malloc() 是正确的?但是我已经读过很多次了,在C 中使用malloc() 的演员是不好的,因为它隐藏了错误!!
  • 我说它在语法上是正确的,并不是说这是一个好习惯。
【解决方案2】:

->第一个问题

memcpy,C 中不需要强制转换。它应该在 C++ 中。

->第二个问题

malloc 返回一个 void 指针 (void *),表示它是一个指向未知数据类型区域的指针。由于强类型系统,在 C++ 中需要使用强制转换,而在 C 中并非如此。根据一些程序员的说法,缺少从 malloc 返回的特定指针类型是类型不安全的行为:malloc 基于字节数分配但不是类型。这与 C++ new 运算符不同,它返回一个类型依赖于操作数的指针

【讨论】:

    【解决方案3】:

    在 C 中,我们直接将 void* 分配给任何类型,反之亦然,我们不必显式地进行类型转换。

    int   *i_ptr = (int *)0xABCD;   //some address
    printf("address :%p\n",i_ptr);
    void  *v_ptr = i_ptr;           //no need to explictly typecast
    printf("address :%p\n",v_ptr);
    float *f_ptr = v_ptr;           //this will throw error in cpp
    printf("address :%p\n",f_ptr);
    

    输出:

    address :0xabcd
    address :0xabcd
    address :0xabcd
    

    所有这些都是 C 中的有效语句,但在 CPP 中 float *f_ptr = v_ptr 会导致错误invalid conversion from 'void*' to 'float*'

    【讨论】:

      猜你喜欢
      • 2021-03-19
      • 1970-01-01
      • 1970-01-01
      • 2014-04-02
      • 2015-12-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多