繁体   English   中英

C 中显式转换为隐式转换

[英]Explicit cast to Implicit cast in C

我想知道是否有可能只用 1 个显式转换就返回相同的结果?

void *begin(void *pt, size_t size)
{
    return (void*)((size_t)pt & -size);
}

每次尝试时,我都会收到 BAD_ACCESS 代码 1

例子:

void *begin(void *pt, size_t size)
{   
    size_t *tmp = pt;
    size_t res = *tmp & -size;
    return (void*)(res);
}

它可以通过零转换完成,使用依赖于实现的代码。 然而,这类似于不使用字母“e”编写代码:这可能是一个挑战,但它在生产代码中毫无用处。 如果它是作为学术练习提出的,它可能很有用,因为人为的约束可以促使学生思考他们可能不会想到的事情,比如做事的替代方法或语言的技术规则。 然而,在实践中,这通常是没有意义的。

您的示例代码使用size_t ,但将地址作为整数处理的首选类型是uintptr_t (如果已定义)。 如果已定义,则在<stdint.h>定义,任何普通的 C 实现,即使质量一般,也应定义它。

您的示例代码假定将地址转换为size_t在内存中生成一个普通整数地址。 address & -size操作是通过清除低位来查找与size的倍数对齐的地址的常用方法,该地址必须是 2 的幂,因此我们认识到您的(size_t) pt必须是一个普通的地址,至少在其低位。)相反,让我们假设一个指针在内存中使用一个普通整数作为地址表示,并且大小与uintptr_t相同。 在其中任何一个为真,另一个也可能为真的任何 C 实现中。 在使用以下代码之前,您应该为目标 C 实现确认这一点。

鉴于这个假设,我们可以在没有强制转换的情况下实现你的begin例程:

#include <stdint.h>
#include <string.h>

void *begin(void *pt, size_t size)
{
    uintptr_t us = size;        // Convert size to uintptr_t to ensure it is at least as wide.
    uintptr_t x;                // Make space to copy pointer.
    memcpy(&x, &pt, sizeof x);  // Copy bytes.
    x &= -us;                   // Zero low bits.
    memcpy(&pt, &x, sizeof pt); // Copy bytes back.
    return pt;
}

如果假设不正确,则仍然可以通过将unsigned char指针设置为unsigned char *p = (unsigned char *) &pt;来为任何选定的 C 实现实现begin unsigned char *p = (unsigned char *) &pt; 然后使用p来检查和操作pt的字节。 C 标准要求每个实现都记录其类型的表示,因此必须记录void * pt字节的含义,这使得编写代码可以根据需要使用它们进行计算。

那使用一个演员表。 它可以通过void *v = &pt; unsigned char *p = v;减少到零void *v = &pt; unsigned char *p = v; void *v = &pt; unsigned char *p = v; .

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM