реклама на сайте
подробности

 
 
> Вычисление констант в процессе компиляции, Всего лишь в пределах 16 бит?
sonycman
сообщение Apr 15 2008, 12:30
Сообщение #1


Любитель
*****

Группа: Свой
Сообщений: 1 864
Регистрация: 20-08-06
Из: Тольятти
Пользователь №: 19 695



Имеется IAR 5.10 и проект на С для ATmega88.
Исходник (кусок):

#define QUARTZ 10000000
#define CLOCK QUARTZ/1000000
#define Wait(mks) __delay_cycles(mks*CLOCK)

Wait(480);

При компиляции идут предупреждения на строку с функцией о выходе значения за пределы диапазона.
Но ведь итоговое значение равно 4800, а параметр __delay_cycles есть unsigned long!
Если CLOCK жестко приравнять к 10, то все нормально.
Но если ее приравнять к 100, то получаем ту-же ошибку out of range плюс еще и о смене знака... :-(

Получается, что компилятор работает с 16-ти битными данными?
Как это побороть?
И почему не работает вышеприведенный пример?
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
VladimirYU
сообщение Apr 15 2008, 12:56
Сообщение #2


Местный
***

Группа: Свой
Сообщений: 426
Регистрация: 5-04-07
Из: Санкт-Петербург
Пользователь №: 26 782



Цитата(sonycman @ Apr 15 2008, 16:30) *
Имеется IAR 5.10 и проект на С для ATmega88.
Исходник (кусок):

#define QUARTZ 10000000UL
#define CLOCK QUARTZ/1000000
#define Wait(mks) __delay_cycles(mks*CLOCK)

Wait(480);


Добавьте UL
Go to the top of the page
 
+Quote Post
sonycman
сообщение Apr 16 2008, 06:43
Сообщение #3


Любитель
*****

Группа: Свой
Сообщений: 1 864
Регистрация: 20-08-06
Из: Тольятти
Пользователь №: 19 695



Цитата(VladimirYU @ Apr 15 2008, 17:56) *
Добавьте UL

Спасибо, добавил, ошибки исчезли, но величина задержки всё равно вычисляется неправильно.
Вот как это выглядит:

Код
#define    QUARTZ    10000000UL            //Crystal quartz frequency
#define    CLOCKS    QUARTZ/1000000UL    //tacts in microsecond

void SomeFunc(void)
{
    volatile unsigned long    a    =    480 * CLOCKS;
}


Так вот, при просмотре отладчиком полученного кода, значение а получается равным 0x0001f9, то есть 505, когда должно быть 4800...
Чёрт, что за глупости smile3046.gif
Причём значения до 420 * CLOCKS обсчитываются правильно, а чуть побольше и пошла бредятина...

Всё, разобрался.
Оказывается эта, извиняюсь за выражение, "тупая скотина" в лице препроцессора или компилятора не вычисляет значение CLOCK, а просто тупо подставляет строку в нужное место.
Например, вышеприведённое выражение принимает вид:
Код
volatile unsigned long    a    =    480 * QUARTZ / CLOCKS

а потом уже компилятор пыжится посчитать:
Код
volatile unsigned long    a    =    480 * 10000000 / 1000000

Естественно, после умножения идёт переполнение за 32 бита, и делению подлежат уже жалкие останки гигантской цифры... 07.gif

Пришлось поставить скобки, теперь вроде всё нормально:
Код
#define    QUARTZ    10000000UL            //Crystal quartz frequency
#define    CLOCKS    (QUARTZ/1000000)    //tacts in microsecond
#define    Wait(mksec)    __delay_cycles(mksec*CLOCKS)

    Wait(480);


На первый взгляд, какого чёрта делают скобки в таком простом выражении?
Ну вот откуда знаешь поначалу такие неявные мелочи?
Go to the top of the page
 
+Quote Post
vet
сообщение Apr 16 2008, 07:05
Сообщение #4


Знающий
****

Группа: Свой
Сообщений: 550
Регистрация: 16-06-04
Из: Казань
Пользователь №: 32



Цитата(sonycman @ Apr 16 2008, 10:43) *
не вычисляет значение CLOCK, а просто тупо подставляет строку в нужное место.

и не будет. препроцессор не знает ничего ни об языке С, ни о формате файлов, которые он обрабатывает; его единственная задача - разворачивать макросы в строки.


--------------------
Главная линия этого опуса ясна мне насквозь!
Go to the top of the page
 
+Quote Post



Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 29th June 2025 - 01:12
Рейтинг@Mail.ru


Страница сгенерированна за 0.01379 секунд с 7
ELECTRONIX ©2004-2016