我试着编译以下函数来看看gcc是怎么做的:
#include <stdint.h>
#include <stddef.h>
typedef struct giga
{
uint64_t g[0x10000000];
} giga;
uint64_t addfst(giga const *gptr, size_t num)
{
uint64_t retval = 0;
for (size_t i = 0; i < num; i++)
{
retval += gptr[i].g[0];
}
return retval;
}
Run Code Online (Sandbox Code Playgroud)
并且发现gcc最大化了我的记忆,将自己交换死亡.
我发现在优化时会发生这种情况-O3
,并未尝试剖析确切的标志.在gcc.godbolt上测试函数显示这是gcc特定的,但是受到了4.8和4.9版本的影响.
这是一个真正的编译器错误,还是我的功能坏了?
无论实际需要多少位,C标准都要求sizeof(char)
为1.
其他数据类型是以字节还是字符来衡量的,以防它们不相同?基本上,假设CHAR_BIT
为16,sizeof(int16_t)
则等于1或2?
struct A
{
uint32_t var1;
uint32_t var2;
uint32_t var3;
uint32_t var4;
uint32_t var5;
};
Run Code Online (Sandbox Code Playgroud)
在上面的结构中,编译器不会填充并分配20个字节.
现在我们有另一个结构,它包含一个8字节变量而不是两个4字节.在这种情况下,编译器填充并为此结构分配24个字节.
struct B
{
uint32_t var1;
uint32_t var2;
uint32_t var3;
uint64_t var5;
};
Run Code Online (Sandbox Code Playgroud)
为什么会出现这种行为?如果编译器将数据对齐到8字节边界,那么在第一个结构中应该有4个字节的填充,并且在这种情况下不应该填充第二个结构.如果编译器将数据对齐到4字节边界,那么为什么在第二个结构中有4个字节的填充?
编译器:GCC平台:64位linux,x86_64
我最近制作了一些矢量代码和一个合适的Godbolt 示例。
typedef float v8f __attribute__((vector_size(32)));
typedef unsigned v8u __attribute__((vector_size(32)));
v8f f(register v8f x)
{
return __builtin_shuffle(x, (v8f){0}, (v8u){1, 2, 3, 4, 5, 6, 7, 8});
}
Run Code Online (Sandbox Code Playgroud)
f:
vmovaps ymm1, ymm0
vxorps xmm0, xmm0, xmm0
vperm2f128 ymm0, ymm1, ymm0, 33
vpalignr ymm0, ymm0, ymm1, 4
ret
Run Code Online (Sandbox Code Playgroud)
我想看看不同的优化 ( -O0/O1/O2/O3
) 设置如何影响代码,并且几乎都-O0
给出了相同的代码。-O0
给出了可预测的帧指针垃圾,并且x
无缘无故地将参数复制到堆栈局部变量。为了解决这个问题,我添加了register
存储类说明符:
typedef float v8f __attribute__((vector_size(32)));
typedef unsigned v8u __attribute__((vector_size(32)));
v8f f(register v8f x)
{
return __builtin_shuffle(x, …
Run Code Online (Sandbox Code Playgroud) 我试图使用递归找出数字的阶乘,并将指针作为函数参数传递.但是这个错误一直出现.经销商和编码员!我需要你的帮助.
The code
#include<stdio.h>
int *factorial(int *);
int value, p=0, q=1, x, tmp;
void main() {
int *result;
puts("Enter the value::");
scanf("%d",&value);
result = factorial(&value);
printf("\nThe Result is::%d\n", *result);
}
int *factorial(int *n) {
if(*n == p || *n == q) {
return(&q);
}
else {
tmp = *n -1;
*n *= (factorial(&tmp));
return(n);
}
}
The error:
error: invalid operands to binary * (have ‘int’ and ‘int *’)
*n *= (factorial(&tmp));
Run Code Online (Sandbox Code Playgroud) 我可以std::transform_reduce
在 Fedora 和 Ubuntu 上使用gcc 9.2.1编译以下代码(使用),但是尝试在 clang see godbolt上编译失败,并且我收到报告说 gcc 9.2.1 的某些 FSF 版本也拒绝编译代码,需要 astd::execution_policy
作为 的第一个参数std::transform_reduce
。
#include <vector>
#include <algorithm>
#include <numeric>
auto brokenvector(std::vector<int> const& a, std::vector<int> const& b)
{
return std::transform_reduce(cbegin(a), cend(a), cbegin(b), 0, std::plus<>{},std::multiplies<>{});
}
Run Code Online (Sandbox Code Playgroud)
我特别不能在std::execution_policy
这里使用 a ,并且cppreference和 C++ 草案标准文档 n4659 都显示了没有执行策略的重载。
我是否进入了某种政治雷区,其中一半可用的编译器拒绝实施该标准,或者代码不正确?