为什么用于取消引用传递给printf的指针的类型会影响输出,即使类型大小相同:
void test_double(void *x)
{
double *y = x;
uint64_t *z = x;
printf("double/double: %lf\n", *y);
printf("double/uint64: %lf\n", *z);
printf("uint64/double: 0x%016llx\n", *y);
printf("uint64/uint64: 0x%016llx\n", *z);
}
int main(int argc, char** argv)
{
double x = 1.0;
test_double(&x);
return 0;
}
输出:
double/double: 1.000000
double/uint64: 1.000000
uint64/double: 0x00007f00e17d7000
uint64/uint64: 0x3ff0000000000000
我希望最后两行都正确打印0x3ff0000000000000,即IEEE754双浮点中1.0的表示形式。
这是未定义的行为。C语言标准规定,如果变量参数没有格式字符串隐含的类型,那么就是UB。在第三个print语句中,您传递了一个双代码,但它期待着一个uint64_t。既然是UB,什么都可能发生。
该规范允许实现在堆栈上传递整数,但通过FPU寄存器传递浮点值,这就是我怀疑在您的测试用例中发生的事情。例如,cdecl调用x86上Linux的约定(GCC)传递x87伪堆栈上的浮点函数参数(寄存器ST0...ST7
)。
如果查看生成的程序集,您可能会发现为什么第三个和第四个print语句的行为不同。在带有Clang 4.1的Mac OS X 10.8.2 64位上,我能够重现类似的结果,程序集看起来像这样,我已经注释了:
.section __TEXT,__text,regular,pure_instructions
.globl _test_double
.align 4, 0x90
_test_double: ## @test_double
.cfi_startproc
## BB#0:
pushq %rbp
Ltmp3:
.cfi_def_cfa_offset 16
Ltmp4:
.cfi_offset %rbp, -16
movq %rsp, %rbp
Ltmp5:
.cfi_def_cfa_register %rbp
pushq %rbx
pushq %rax
Ltmp6:
.cfi_offset %rbx, -24
# printf("%lf", double)
movq %rdi, %rbx
movsd (%rbx), %xmm0
leaq L_.str(%rip), %rdi
movb $1, %al
callq _printf
# printf("%lf", uint64_t)
movq (%rbx), %rsi
leaq L_.str1(%rip), %rdi
xorb %al, %al
callq _printf
# printf("%llx", double)
leaq L_.str2(%rip), %rdi
movsd (%rbx), %xmm0
movb $1, %al
callq _printf
# printf("%llx", uint64_t)
leaq L_.str3(%rip), %rdi
movq (%rbx), %rsi
xorb %al, %al
addq $8, %rsp
popq %rbx
popq %rbp
jmp _printf ## TAILCALL
.cfi_endproc
在打印一个double
值的情况下,它将参数放入SIMD%xmm0
寄存器:
movsd (%rbx), %xmm0
但是在uint64_t
值的情况下,它通过整数寄存器%rsi
传递参数:
movq (%rbx), %rsi
我需要编写一个java方法来从一个对象中获取特定的信息。但是,该对象可以是A类型的,也可以是B类型的。下面是我的代码的一部分: 当我这样写它时,它会引发一个错误,说“重复方法”。我怎么才能让这个起作用?
我在试验inttype. h时做的简单程序: 在我的手机(64位八核ARN LTE Soc Android 10)它的工作原理很好: 但在我的计算机(64位x86 Windows 10)上,我得到: 将bool更改为uint8_t不会影响它。 编辑:我尝试用MinGW-w64 GCC C99和C17编译。
这个应用程序的每个JVM应该使用相同的数据库吗?否则跟踪令牌不会在同一个应用程序中“共享”? 如何在运行传奇的相同应用程序中拆分事件?一个saga类型或saga实例是否总是在同一个应用程序上处理(直到它被关闭,所以另一个实例负责它)? 还是每个JVM都接收事件,并且每个相同类型的传奇都将运行?(并导致发送重复命令和错误) 等。还有很多问题。
这是代码: 如果我在我的机器()或这里()上尝试: 相反,这里(): 这是不同的。这是由于机器厄普西隆?还是编译器精度标志?还是不同的评估? 造成这种漂移的原因是什么?问题似乎出现在函数中(因为其他值似乎相同)。
问题内容: 当与MySQL数据库连接时,我有几种方法可以做同样的事情,保存或加载不同类型的参数。目前,我对每种类型都有不同的方法。如何合并这些方法,以便它们支持不同的类型? 下面是两个非常相似但使用不同类型的方法的示例: 请注意,在该示例中,类型均为数字。在类型完全不同的情况下(例如int和String),如何避免使用近乎重复的方法? 问题答案: 您可以在此处应用 策略 模式。 …