Условная компиляция в зависимости от sizeof(double)
Есть макрос (#define ...) где-то в недрах с Arduino IDE или основных заголовочных файлов, которая говорит мне, что во время компиляции(!), если двойной
тип данных для конкретной платформы/платы-это настоящий двойной точности с плавающей запятой (64 разрядность), или "всего лишь" псевдоним для одинарной точности с плавающей запятой (32 бит шириной)?
С Arduino и то, и другое может иметь место. 8-битные платы AVR имеют double
равную float
точность , платы на базе ARM (например, Arduino Zero) поддерживают "истинную" двойную точность.
Я работаю над библиотекой, которая реализует некоторую битовую обработку чисел с плавающей запятой (как одинарной, так и двойной точности). Из-за низкоуровневой природы проблемы должны существовать отдельные функции для float
и double
. Я хотел бы сделать что - то вроде этого:
uint32_t function_for_float(float f) {
// function body here...
}
#if defined(HAS_64_BIT_DOUBLE)
uint64_t function_for_double(double d) {
// function body here...
}
#endif
Таким образом, ошибка времени компиляции будет сгенерирована, если кто-то попытается использовать версию "double" на платформах, которые не поддерживают тип данных "true" double. Я хочу, чтобы ошибка компилятора была сгенерирована, потому что функция function_for_double()
будет молча делать "неправильную вещь" при подаче float с одинарной точностью, что потенциально приведет к трудным для отладки проблемам.
Прямо сейчас я определяю макро-константу для каждой соответствующей платы, которой владею, например:
#if defined(ARDUINO_SAMD_ZERO) \
|| defined(SAMD_FEATHER_M0_EXPRESS) \
|| defined(ADAFRUIT_FEATHER_M4_EXPRESS)
#define HAS_64_BIT_DOUBLE
#endif
Но это уродливо и не перспективно (новые платы могут/станут доступны...).
Есть предложения?
@Andy, 👍2
Обсуждение1 ответ
Лучший ответ:
Двойной
тип данных почти повсеместно имеет длину 8 байт, так что вы можете
просто
#if !__AVR__
# define HAS_64_BIT_DOUBLE
#endif
Однако Gcc предоставляет более специфичный макрос: __SIZEOF_DOUBLE__
, который
имеет то же значение, что и sizeof(double)
. Но я не знаю
, обеспечивается ли это другими компиляторами.
Идеально! Я буду использовать макросы __SIZEOF_DOUBLE__
и __SIZEOF_DOUBLE__
, даже если они специфичны для gcc/g++. В любом случае, Arduino IDE использует g++ в качестве своего бэкенда, так что для меня этого "достаточно"., @Andy
Только что проверил, что " __SIZEOF_DOUBLE__ == 4 на Arduino Pro Mini (AVR 328p) и
__SIZEOF_DOUBLE__ == 8` на Adafruit Feather M0 (ARM Cortex-M0+ / SAMD21). Большое спасибо! Я выбрал ваш ответ как правильный., @Andy
- Ошибка Cast from 'char*' to 'uint8_t {aka unsigned char}' loses precision [-fpermissive]
- Поскольку double и float представляют один и тот же тип данных (обычно), что предпочтительнее?
- Как загрузить уже скомпилированный код, когда никаких изменений не производилось?
- ESP32 в Arduino IDE: определите тип платы в коде (макрос препроцессора)
- Есть ли ограничения на размер массива в Arduino Mega 2560?
- Что мне делать с StackOverflow при ошибке компиляции?
- Как заставить Arduino IDE использовать определенную версию GCC в Debian?
- Как иметь в проекте код, который не будет компилироваться для Arduino?
Это на самом деле не вопрос Arduino. Arduino использует g++ для компиляции, поэтому ваш вопрос действительно "может ли g++ сделать это?" Судя по [этому](https://stackoverflow.com/questions/4079243/how-can-i-use-sizeof-in-a-preprocessor-macro) - не совсем. Вы можете утверждать, что double не 8 байт (я проверил это), но не делать выбор, если нет другого хитрого способа сделать это., @Nick Gammon
@NickGammon: Спасибо за ссылку. У меня на самом деле есть " static_assert(sizeof(double) == 8)
в коде моей "двойной функции". Однако тогда полный файл library .cpp не будет компилироваться на платформах, где
double` имеет только четыре байта. Именно это и заставило меня задуматься об условном дополнении в первую очередь. Я хотел бы генерировать ошибку компилятора только в том случае, если sombody пытается использовать двойную версию, когда он не должен. Где-то в Arduino наверняка должно быть определено, что double равно float? Я надеюсь(г) использовать это как крюк каким-то образом..., @Andy