[英]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?
这可能是什么原因?
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
.例如,
41680900
是0x027C0004
,您可以在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.