sizeof (float) дает неверный результат на atmega2560 - PullRequest
0 голосов
/ 27 июня 2019

Я работаю с контроллером atmega2560 и avr-g ++. Я отлаживаю код, который работает на моем хосте Ubuntu 18.04 (при компиляции с g ++), но не на atmega2560. Я подумал, что это может быть проблемой с различными размерами типов данных, и использовал этот код для исследования (также приведенный ниже):

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

Результаты на хосте выглядят нормально, но скомпилированный код avr-g ++ на atmega2560 дает большие размеры для разных типов данных:

г ++:

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

.avr-г ++:

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

что совершенно нереально. Что может быть причиной этого?

обновление

Было предложено попробовать% zu вместо% ld, чтобы напечатать выходные данные std :: size_t из sizeof (...). Это, к сожалению, не сработало, и результат выглядит следующим образом:

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

Ответы [ 2 ]

1 голос
/ 01 июля 2019

На atmega2560 целое число составляет 2 байта. Таким образом, каждый из ваших вызовов printf передает строку формата, за которой следует 2-байтовое целое число.

Но строка формата указывает %ld, что является 4-байтовым long целым числом; поэтому printf ожидает 4-байтовое значение в стеке. Поэтому он читает байты из стека, которые не были переданы вызывающей функцией; эти байты могут иметь любое значение.

Если бы вы напечатали значения в шестнадцатеричном формате с %lX, вы бы увидели ожидаемый размер в младших двух байтах. Например, 41680900 - это 0x027C0004, и вы можете увидеть размер float в этом 0004. 027C - фактически случайный шум.

Чтобы исправить это, используйте %d вместо %ld. Это будет работать на вашем хосте Ubuntu (с 4-байтовыми целыми числами) и на вашем atmega2560 (с 2-байтовыми целыми числами).

Возможно, еще лучше использовать %z, как объясняется в ответе Чукса, в случае, если размер sizeof не совпадает с размером int.

1 голос
/ 01 июля 2019

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 ++, как насчет следующего? @ Боб __

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