[英]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.