gpt4 book ai didi

c - 一些 C++ 转换为 C,仍然遵循标准?

转载 作者:太空宇宙 更新时间:2023-11-04 02:27:01 27 4
gpt4 key购买 nike

好的,所以 Stockfish 项目有这段代码,它允许存储两个整数(预计在 ~[-16000, 16000] 之间)

编辑:我忘记提了,这样做的全部目的是我们可以一次将两个整数相加。浏览器

a1+a2,b1+b2 = Decode(Encode(a1,b1) + Encode(a2,b2))

constexpr int make_score(int mg, int eg) {
return (int)((unsigned int)eg << 16) + mg;
}

inline int eg_value(int s) {
union { uint16_t u; int16_t s; } eg = { uint16_t(unsigned(s + 0x8000) >> 16) };
return (int)eg.s;
}

inline int mg_value(int s) {
union { uint16_t u; int16_t s; } mg = { uint16_t(unsigned(s)) };
return (int)mg.s;
}

我想将其转换为 C。显然我可以跳过 inline 和 constexpr 限定符。但是,不允许使用内联 union 定义。此外,我不希望使用 union ,因为它在 IMO 看来不合时宜。

这是我用 C 写的

#define MakeScore(mg, eg) ((int)((unsigned int)(eg) << 16) + (mg))

#define ScoreMG(s) ((int16_t)((uint16_t)((unsigned)((s)))))

#define ScoreEG(s) ((int16_t)((uint16_t)((unsigned)((s) + 0x8000) >> 16)))

据我的测试所知,在 c++ 和 c 程序之间进行比较时,这两个版本的行为相同。主要区别是我用一个简单的转换为 int16_t 替换了 mg.s 或 eg.s 的最后一步(获取 union 的签名部分)。

对于任何 C 标准(使用 C98,但此处的任何版本都可能相同)的任何部分的任何想法或方向,我们将不胜感激。

最佳答案

代码可以用 C++ 简化,然后是有效的 C:

int eg_value2(int s) {
return ((unsigned)s + 0x8000u) >> 16;
}

它生成与原始程序集相同的程序集:

lea eax,[rdi+0x8000]
shr eax,0x10
ret

顺便说一句,原始代码写入 union 体的一个成员,然后从另一个成员读取,这在 C++ 中是未定义的行为。参见 Accessing inactive union member and undefined behavior?

关于c - 一些 C++ 转换为 C,仍然遵循标准?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49595342/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com