简体   繁体   English

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

[英]sizeof(float) giving wrong result on atmega2560

I'm working with the atmega2560 controller and avr-g++.我正在使用 atmega2560 控制器和 avr-g++。 I'm debugging code that works on my Ubuntu 18.04 host (when compiled with g++) but not on the atmega2560.我正在调试适用于我的 Ubuntu 18.04 主机(使用 g++ 编译时)但不适用于 atmega2560 的代码。 I thought it might be a problem of different data type sizes, and used this code to investigate (also given below):我认为这可能是不同数据类型大小的问题,并使用代码进行调查(也在下面给出):

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));

The results on the host look ok but the avr-g++ compiled code on atmega2560 gives wild sizes for the different data types:主机上的结果看起来不错,但 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++: avr-g++:

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

which is completely unrealistic.这是完全不现实的。 What could be the reason for this?这可能是什么原因?

update更新

It was suggested that I try %zu instead of %ld to print the std::size_t outputs from sizeof(...).有人建议我尝试使用 %zu 而不是 %ld 来打印 sizeof(...) 的 std::size_t 输出。 This, unfortunately, didn't work, and the output looks as follows:不幸的是,这不起作用,输出如下所示:

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

On the atmega2560, an integer is 2 bytes.在 atmega2560 上,一个整数是 2 个字节。 So each of your calls to printf is passing the format string, followed by a 2-byte integer.因此,您对printf每次调用都会传递格式字符串,后跟一个 2 字节整数。

But the format string specifies %ld , which is a 4-byte long integer;但是格式字符串指定了%ld ,它是一个 4 字节long整数; so printf is expecting a 4-byte value on the stack.所以printf期望堆栈上有一个 4 字节的值。 It is therefore reading bytes from the stack that weren't pushed there by the calling function;因此,它从堆栈中读取未被调用函数推送到那里的字节; these bytes could have any value whatsoever.这些字节可以有任何值。

If you had printed the values in hexadecimal with %lX , you would have seen the expected size in the low-order two bytes.如果您使用%lX以十六进制打印值,您将看到低位两个字节的预期大小。 For example, 41680900 is 0x027C0004 , and you can see the size of a float in that 0004 .例如, 416809000x027C0004 ,您可以在0004看到float的大小。 The 027C is effectively random noise. 027C是随机噪声。

To fix this, use %d instead of %ld .要解决此问题,请使用%d而不是%ld This will work on your Ubuntu host (with 4-byte integers) and your atmega2560 (with 2-byte integers).这将适用于您的 Ubuntu 主机(使用 4 字节整数)和您的 atmega2560(使用 2 字节整数)。

Perhaps even better is to use %z , as explained in chux's answer, in case the size of a sizeof is not the same as the size of an int .也许更好的是使用%z ,如 chux 的回答中所述,以防sizeof的大小与int的大小不同。

sizeof returns a size_t - some unsigned type. sizeof返回一个size_t - 一些无符号类型。 When using *printf() , use the specified matching specifier of "zu "`.使用*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);

If code is using an old version casting to the widest available type is an alternative:如果代码使用旧版本转换为最广泛的可用类型,则另一种选择:

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

Of course with small result expected, code could use unsigned当然,预期结果很小,代码可以使用unsigned

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

Yet since this is C++, how about the following?然而,既然这是 C++,那么下面呢? @Bob__ @鲍勃__

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM