Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/70.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 到未签名并返回:强制转换指针与强制转换取消引用_C_Pointers_Casting_Lua_Unsigned - Fatal编程技术网

C 到未签名并返回:强制转换指针与强制转换取消引用

C 到未签名并返回:强制转换指针与强制转换取消引用,c,pointers,casting,lua,unsigned,C,Pointers,Casting,Lua,Unsigned,假设您不关心编译器和机器的转换样式,那么以下两者之间是否存在明显的差异: #包括 #包括 #包括 静态int64_t已签名(void*p) { 返回*(int64_t*)p; } 内部主(空) { int64_t i=0xfabf00d0badf00d; uint64_t u=0xabad1deacafebe; printf(“%”PRId64“\n“%”PRId64“\n”、tosigned(&i)、tosigned(&u)); 返回0; } 这个呢 #包括 #包括 #包括 静态int64_

假设您不关心编译器和机器的转换样式,那么以下两者之间是否存在明显的差异:

#包括
#包括
#包括
静态int64_t已签名(void*p)
{
返回*(int64_t*)p;
}
内部主(空)
{
int64_t i=0xfabf00d0badf00d;
uint64_t u=0xabad1deacafebe;
printf(“%”PRId64“\n“%”PRId64“\n”、tosigned(&i)、tosigned(&u));
返回0;
}
这个呢

#包括
#包括
#包括
静态int64_t已签名(void*p,int为未签名)
{
返回是无符号的?(int64\u t)*(uint64\u t*)p:*(int64\u t*)p;
}
内部主(空)
{
int64_t i=0xfabf00d0badf00d;
uint64_t u=0xabad1deacafebe;
printf(“%”PRId64“\n“%”PRId64“\n”、tosigned(&i,0)、tosigned(&u,1));
返回0;
}
对于
-O2
和更高版本,使用
clang-S-std=c99-Wall-Wextra
的程序集转储显示输出没有差异。然而,我想知道是否有一种更“正确”的方法来实现它,或者第一种方法是否会遇到未定义或特定于实现的行为

我假设转换为指向相同类型的无符号版本的指针与转换指针取消引用的结果一样

背景:

我当时正在为Lua编写一个int64库,在为算术打字时遇到了这个学术问题


我将int64_t和uint64_t用户数据(存储在Lua运行时中的不透明C blob)存储在Lua堆栈上。有一些“元方法”被指定用于执行算术,例如,
“\uu添加”
,用于
x+y
,而不是引发类型错误,因为您(通常)无法对非数字执行算术。但是,有符号值和无符号值存储为不同的类型,因此不兼容。我对第二个论点做了更广泛的转换,将其转换为与第一个论点相同的符号。
isunsigned
参数大致匹配“这是否有一个无符号类型表?”。运行时为存储值返回一个空指针,转换方式由您决定。

C标准允许使用第一种方法,即强制转换指针,因为C 2011(N1570)6.5 7允许通过与对象的有效类型相对应的有符号或无符号类型访问对象。也就是说,您可以访问一个无符号整数作为大小相同的有符号整数,反之亦然。(应该注意的是,这种别名是C标准明确允许的一种特殊情况。许多其他指针强制转换以及随后的取消引用都会违反6.5.7中规定的别名规则。)


如果值在目标类型(6.3.1.3 1)中可表示,则第二种方法(将整数强制转换为有符号整数)由C标准定义,而实现是以其他方式定义的(并且可能会出现陷阱)(6.3.1.3 3)。

我认为没有任何区别,但是仅仅使用函数进行强制转换似乎有些过分。对于Lua的int64库,请参阅,但它只支持带符号的数字。OTOH,有符号和无符号的算术是一样的,只是它们的比较和打印方式不同。