我相信我在执行O'Neill的PCG PRNG时在GCC中发现了一个bug。(Godbolt的编译器资源管理器上的初始代码)
#include <stdint.h>
struct retstruct {
uint32_t a;
uint64_t b;
};
struct retstruct fn(uint64_t input)
{
struct retstruct ret;
ret.a = 0;
ret.b = input * 11111111111 + 111111111111;
return ret;
}
生成的程序集(GCC 9.2,x86_64,-O3):
fn:
movabs rdx, 11111111111 # multiplier constant (doesn't fit in imm32)
xor eax, eax # ret.a = 0
imul rdi, rdx
movabs rdx, 111111111111 # add constant; one more 1 than multiplier
# missing add rdx, rdi # ret.b=... that we get with clang or older gcc
ret
# returns RDX:RAX = constant 111111111111 : 0
# independent of input RDI, and not using the imul result it just computed
有趣的是,修改结构以使uint64_t作为第一个成员产生正确的代码,就像将两个成员都更改为uint64_t一样
x86-64 System V在rdx:rax中返回小于16字节的结构,但它们是可以复制的。在本例中,第二个成员是RDX,因为RAX的高半部分是用于对齐或.b
的填充,而.a
是较窄的类型。(sizeof(retstruct)
无论哪种方式都是16;我们没有使用__attribute__((packed))
,因此它尊重alignof(uint64_t)=8。)
如果没有,应该在https://gcc.gnu.org/bugzilla/上报告这一点
我在这里没有看到任何UB;您的类型是未签名的,所以签名溢出UB是不可能的,没有什么奇怪的。(即使签名,它也必须为不会导致溢出UB的输入产生正确的输出,如rdi=1
)。它也被GCC的C++前端打破了。
此外,GCC8.2为AArch64和RISC-V正确编译了它(在使用movk
构造常数之后,将其编译为madd
指令,或者在加载常数之后,将其编译为RISC-V mul和add指令)。如果GCC找到的是UB,我们通常希望它找到UB,并为其他ISA破译代码,至少是具有类似类型宽度和寄存器宽度的ISA破译代码。
Clang也会正确地编译它。
您可以使用问题中的MCVE在GCC的bugzilla上报告这一点。
这看起来确实是x86-64 System V结构返回处理中的一个bug,可能是包含填充的结构。这就解释了为什么它在内联和将A
扩展为uint64_t(避免填充)时起作用。
我正在等待(从USSD请求中)检索一个值,以便返回它(getUSSD):
我正在用Python作为后端编写一个应用程序,当我试图返回一个函数的变量时,我得到以下错误 这是我使用的代码 有人知道这个问题的答案吗?
问题内容: 这是输出: 为什么JSON本质上是空的? 问题答案: 您需要通过大写字段名称中的第一个字母来导出 TestObject中的字段。更改为,依此类推。 encoding / json包和类似的包会忽略未导出的字段。 字段声明之后的字符串是struct标签。在与JSON封送时,此struct中的标记设置该结构的字段名称。
我接受了一次采访,被问到一个问题,我想了解解决方案。 创建一个递归函数,该函数返回给定长度的数组的可能组合数,这些数组可以由非重复连续整数数组组成。 f(数组,长度)=组合 数组=[0,1,2,3] 长度=2 组合=10(所有组合:[0,0][0,1][0,2][0,3][1,1][1,2][1,3][2,2][2,3][3,3]) 请注意,允许使用[0,0],但不允许使用[1,0],因为定义了[
我正在使用Tensorflow和Flask开发一个python(3.6)项目。我需要在flask函数中运行Tensorflow模型,但它返回一个错误。 这是我的密码: 应用程序。派克 但当我运行我的flask应用程序时,它返回错误为: 2018-09-05 11:08:54.952 Python[3772:69116]警告:NSWindow拖动区域只能在主线程上无效!这将在中引发异常 未来。从(0
我得到了这个错误,我知道这个问题已经在这里解决过了,因为人们没有在函数中添加返回->。我不明白为什么这仍然给我带来错误。