неявное преобразование типов данных

knik777
Offline
Зарегистрирован: 26.09.2015

Добрый день!

Подскажите, как правильно нужно писать, чтобы не было неявного преобразования типов.

Вот этот код не работает:

int a=5000;

void loop() {

....

lastmove=millis();

....

if (millis()-lastmove<a*1UL)

{ delaem.....}}

 

А вот этот код работает:

void loop() {

....

lastmove=millis();

....

if (millis()-lastmove<5000UL)

{ delaem.....}}

Нужно задать время (5000 мс) через переменную. как это правильно сделать?

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

 

Какой тип возвращает millis()? Посмторите её описание. Возвращает она unsigned long. Ну так и описывайте переменную для сравнения с нею этим же типом:

unsigned long a=5000;

knik777
Offline
Зарегистрирован: 26.09.2015

по другому никак? А почему не работает (a*1UL)?

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

А lastmove как описано?

knik777
Offline
Зарегистрирован: 26.09.2015

unsigned long lastmove=1UL;

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Понятно. Ну и что Вас не устраивает? Для чего Вы спрашиваете "по другому никак?". Для чего Вам по-другому?

Почему не работает a*1UL? Вам это из академических соображений интересно? Возможно, потому что константа 1 вполне помещается в int. См. п. 6.3.1.1.2 стандарта С

If an int can represent all values of the original type (as restricted by the width, for a bit-field), the value is converted to an int; otherwise, it is converted to an unsigned int. These are called the integer promotions.58) All other types are unchanged by the integer promotions

Также см. п. 6.3.1.3 того же стандарта:

6.3.1.3 Signed and unsigned integers
1 When a value with integer type is converted to another integer type other than _Bool, if
the value can be represented by the new type, it is unchanged.
2 Otherwise, if the new type is unsigned, the value is converted by repeatedly adding or
subtracting one more than the maximum value that can be represented in the new type
until the value is in the range of the new type.
3 Otherwise, the new type is signed and the value cannot be represented in it; either the
result is implementation-defined or an implementation-defined signal is raised.

Обычно (в большинстве компиляторов) всё работает с преобразованием. Но стандарт, как видите, допускает двойное толкование для констант поэтому, возможно (я далеко не уверен) в Вашем случае преобразование не проведено, хотя я бы проверил это отдельно. 

А вообще, преобразования типов нужно делать явно. Стандарты неявного преобразования во-первых сильно запутаны и местами неоднозначны, а во-вторых - это то, что разработчики реализаций нарушают наиболее часто.