根据这篇关于c语言中未定义行为优化的有趣文章,表达式(x
考虑以下代码:
#include <stdio.h>
#include <stdint.h>
uint32_t rotl(uint32_t x, uint32_t n)
{
return (x << n) | (x >> (32 - n));
}
int main()
{
uint32_t y = rotl(10, 0);
printf("%u\n", y);
return 0;
}
使用以下参数编译:
-O3-std=c11-pedantic-Wall-Wextra
在gcc中
有趣的是,当使用c编译时,这仍然是正确的:gcc结果,clangresults。
因此,我的问题如下:
我从标准中的语言中理解,这不应该调用未定义/实现定义的行为,因为两个参数都是无符号整数,并且没有一个值是负的。这是正确的吗?如果不是,c11和c 11的相关部分是什么?
- 如果前面的语句为真,哪个编译器正在根据c/c标准产生正确的输出?直观地说,左移没有数字应该会给您返回值,即gcc输出的内容。
- 如果上述情况并非如此,为什么没有警告此代码可能会因左移溢出而调用未定义的行为?
如果n
为0,32-n
为32,由于x
有32位,x
链接SO帖子中的问题是不同的。这个与签名无关。
你的n
是0
,所以执行x
源自[expr.shift],强调我的:
如果右操作数为负,或大于或等于提升后的左操作数的位长度,则行为未定义。
你正在做:
(x >> (32 - n))
使用n==0
,则将32位数字右移32位。因此,乌布。
我试图使用clang和gcc交叉编译一个项目,但在使用时,我发现了一些奇怪的差异,例如。 现在,当涉及NAN时,我期望类型行为,但clang和gcc给出不同的结果: 当我使用它时,_mm_max_ps做了预期的事情。我尝试过使用,,但似乎没有效果。有什么想法可以让编译器之间的行为相似吗? 这里是锁销连接
当一个类具有 constexpr 成员函数并且该成员函数正在 constexpr 上下文中的 l 值对象上求值时,clang 和 gcc 不同意结果是否为 constexpr 值。为什么?是否有既不需要默认可构造性也不需要复制可构造性的解决方法? 当对象按值传递时,两个编译器都会成功编译。 Clang版本trunk,8,7: 和 gcc 版本主干,8.1、7.4:编译没有错误 https://go
为什么无符号右移(逻辑右移)和有符号右移(算术右移)对负数产生相同的结果? Android Studio Logcat输出
下面的例子可以解释我的意思: <代码>自动p=标准::使\u共享 变量是默认初始化的(因此具有垃圾值)还是值初始化的(因此具有零值)?我在GCC 5.2和clang 3.6上进行了测试,前者进行值初始化,后者进行默认初始化。我想知道标准对此有什么规定?在我看来,在这种情况下,现代C肯定应该执行值初始化。
问题内容: 我刚刚注意到了这一点: 为什么这两行的输出不同? 我无法分享确切的数据,但我将尝试提供尽可能多的详细信息: 感谢@jezrael和@ayhan,这就是发生的事情,让我使用@jezael提供的示例: 如果我们看一下第3行: 以及我写条件的方式: 由于符号的优先级高于,因此不带方括号的等效于: 带括号: 我认为用数字说明这个问题要容易一些: 因此,经验教训是:总是加括号!!! 我希望我可以
精明的加法学专家会注意到,它只能加到62位。我在编译器和芯片设计方面的经历告诉我,保留位值黄金。所以我们有两个(设置为零)。 那么这是否意味着: 问题一: ~表示36位移位,包含10位类型Id和其余36位本地Id: #00000000000000000000# ShardID 3429的 二进制=1101 0110 0101 因此(hashedValue>>46)=00000 0 110 1 01