sizeof(float)在atmega2560上给出了错误的结果

时间:2019-06-27 09:25:09

标签: c++ floating-point avr sizeof atmega

我正在使用atmega2560控制器和avr-g ++。我正在调试适用于我的Ubuntu 18.04主机(使用g ++编译时)但不能在atmega2560上运行的代码。我认为这可能是不同数据类型大小的问题,并使用this代码进行调查(也在下面给出):

int integerType;
float floatType;
double doubleType;
char charType;

printf("Size of int: %ld bytes\n",sizeof(integerType));
printf("Size of float: %ld bytes\n",sizeof(floatType));
printf("Size of double: %ld bytes\n",sizeof(doubleType));
printf("Size of char: %ld byte\n",sizeof(charType));

主机上的结果看起来还不错,但是atmega2560上的avr-g ++编译代码给出了不同数据类型的大小:

g ++:

Size of int: 4 bytes
Size of float: 4 bytes
Size of double: 8 bytes
Size of char: 1 byte

avr-g ++:

Size of int: 2 bytes
Size of float: 41680900 bytes
Size of double: 43253764 bytes
Size of char: 44957697 byte

这是完全不现实的。可能是什么原因?

更新

建议我尝试%zu而不是%ld从sizeof(...)打印std :: size_t输出。不幸的是,这没有用,输出结果如下:

Size of int: Size of float: Size of double: Size of char: 

2 个答案:

答案 0 :(得分:1)

sizeof返回size_t-一些 unsigned 类型。使用*printf()时,请使用"zu“`的指定匹配说明符。

// printf("Size of float: %ld bytes\n",sizeof(floatType));
// () not needed with an object
printf("Size of float: %zu bytes\n", sizeof floatType);

如果代码使用的是旧版本,则将其强制转换为最大可用类型:

// Assume unsigned long is widest
printf("Size of float: %lu bytes\n", (unsigned long) sizeof floatType);

当然,预期结果很小,代码可以使用unsigned

printf("Size of float: %u bytes\n", (unsigned) sizeof floatType);

然而,既然这是C ++,那么以下内容呢? @Bob__

cout << "Size of float: " << sizeof floatType << " bytes" << endl;

答案 1 :(得分:1)

在atmega2560上,整数是2个字节。因此,您对25的每次调用都传递格式字符串,后跟2个字节的整数。

但是格式字符串指定 #include <iostream> #include <math.h> // Kernel function to add the elements of two arrays __global__ void add(int n, float *x, float *y) { for (int i = 0; i < n; i++) y[i] = x[i] + y[i]; } int main(void) { int N = 1<<24; float *x, *y; // Allocate Unified Memory – accessible from CPU or GPU cudaMallocManaged(&x, N*sizeof(float)); cudaMallocManaged(&y, N*sizeof(float)); // initialize x and y arrays on the host for (int i = 0; i < N; i++) { x[i] = 1.0f; y[i] = 2.0f; } // Run kernel on 1M elements on the GPU add<<<1, 1>>>(N, x, y); // Wait for GPU to finish before accessing on host cudaDeviceSynchronize(); // Check for errors (all values should be 3.0f) float maxError = 0.0f; for (int i = 0; i < N; i++) maxError = fmax(maxError, fabs(y[i]-3.0f)); std::cout << "Max error: " << maxError << std::endl; // Free memory cudaFree(x); cudaFree(y); return 0; } ,它是4字节的printf整数;因此%ld期望堆栈中的值为4字节。因此,它是从堆栈中读取未被调用函数压入的字节。这些字节可以具有任何值。

如果使用long以十六进制形式打印值,则可以看到低位两个字节的预期大小。例如,printf%lX,您可以在该41680900中看到0x027C0004的大小。 float实际上是随机噪声。

要解决此问题,请使用0004而不是027C。这将在您的Ubuntu主机(具有4个字节的整数)和atmega2560(具有2个字节的整数)上工作。

如chux的答案所述,最好使用%d,以防%ld的大小与%z的大小不同。