【问题标题】:sizeof(float) giving wrong result on atmega2560sizeof(float) 在 atmega2560 上给出错误的结果
【发布时间】:2019-06-27 09:25:09
【问题描述】:

我正在使用 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: 

【问题讨论】:

  • 根据this的回答,正确的说明符是%zu。也许这就是问题所在。
  • 如果对返回类型有疑问,可以试试std::cout << sizeof(.) << "\n"
  • l 在该格式表达式中没有位置。我似乎已经提到了这一点。 sizeof 也是一个运算符,而不是一个函数:它不需要括号。
  • 似乎 sizeof() 在 avr-g++ 上返回 unsigned ints,而不是 unsigned longs。因此,如果您删除 l,您将看到正确的结果。
  • 好吧,你总是可以使用丑陋的演员表:printf("Size of float: %d bytes\n", (int)sizeof(float));,但你为什么不使用std::cout

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


【解决方案1】:

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

但是格式字符串指定了%ld,这是一个4字节的long整数;所以printf 期望堆栈上有一个 4 字节的值。因此,它正在从堆栈中读取调用函数未推送到那里的字节;这些字节可以有任何值。

如果您使用%lX 打印了十六进制值,您会看到低位两个字节的预期大小。例如,416809000x027C0004,您可以在0004 中看到float 的大小。 027C 实际上是随机噪声。

要解决此问题,请使用 %d 而不是 %ld。这将适用于您的 Ubuntu 主机(使用 4 字节整数)和 atmega2560(使用 2 字节整数)。

也许更好的是使用%z,正如chux的回答中所解释的那样,以防sizeof的大小与int的大小不同。

【讨论】:

    【解决方案2】:

    sizeof 返回一个size_t - 一些无符号 类型。使用*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;
    

    【讨论】:

      猜你喜欢
      • 2014-09-16
      • 2017-11-20
      • 2011-11-15
      • 2019-02-06
      • 2014-01-30
      • 2018-08-01
      • 2016-08-30
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多