Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Keil
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
demiurg_spb
Опции компиляции:
Код
--feedback ".\obj\xxxx.fed" -c --cpu Cortex-M3 -D__MICROLIB  -g -O3 -Otime --apcs=interwork --split_sections --asm --interleave --C99  --asm --interleave -I "C:\Keil\\ARM\INC" -I

Пример:
Код
float func(float x)
{
    return (x*pow(0.1, 0.01));
}

Этот негодяй прилинковывает функцию pow и по ходу дела считает её в рантайме, а не на этапе компиляции.
С gcc таких сюрпризов не припоминаю.
Есть идеи куда копать?
scifi
Цитата(demiurg_spb @ Apr 29 2011, 12:32) *
Этот негодяй прилинковывает функцию pow и по ходу дела считает её в рантайме, а не на этапе компиляции.

С более чем 10 годами опыта программирования на Си я всегда считал, что иначе и быть не может.

Цитата(demiurg_spb @ Apr 29 2011, 12:32) *
С gcc таких сюрпризов не припоминаю.

GCC вычисляет это на этапе компиляции? Если это правда, моё мнение о GCC резко улучшается :-)

Цитата(demiurg_spb @ Apr 29 2011, 12:32) *
Есть идеи куда копать?

Конечно.
return x * 0.97723722f;
demiurg_spb
Цитата(scifi @ Apr 29 2011, 13:22) *
С более чем 10 годами опыта программирования на Си...

Ну мы с Вами по этому параметру близнецы братья:-), но я по большей части всё это время сидел под GCC.
Цитата
GCC вычисляет это на этапе компиляции? Если это правда, моё мнение о GCC резко улучшается :-)
А что тут странного?
constant propagation - уже сто лет в обед.
Цитата
return x * 0.97723722f;
Так и сделано сейчас, но это не удобно, т.к. это число должно зависеть от задефайненого значения. Некрасиво....
(грубо это коэффициент фильтра, зависящий от ADC_SMP_RATE, который должен пересчитываться на этапе компиляции.
а ADC_SMP_RATE - любое целое положительное число>0)
scifi
Цитата(demiurg_spb @ Apr 29 2011, 14:39) *
constant propagation - уже сто лет в обед.

Обычно constant propagation ничего не знает про функции. А gcc постарался - молодцы.

Цитата(demiurg_spb @ Apr 29 2011, 14:39) *
Так и сделано сейчас, но это не удобно, т.к. это число должно зависеть от задефайненого значения. Некрасиво....
(грубо это коэффициент фильтра, зависящий от ADC_SMP_RATE, который должен пересчитываться на этапе компиляции.
а ADC_SMP_RATE - любое целое положительное число>0)

Ну, можно прикрутить костыль: assert(проверить, что значения двух констант согласованы). Тогда если изменили одну константу, но забыли подправить другую, это вылезет на этапе отладки. Другие варианты тоже так себе: внешний скрипт для генерации констант, инициализация константы в ОЗУ при старте программы.
ViKo
Цитата(scifi @ Apr 29 2011, 15:22) *
Ну, можно прикрутить костыль: assert(проверить, что значения двух констант согласованы).

А вот assert как раз работает на этапе run-time, нет?
А проверять при компиляции - только #if ... #error. Правильно?
scifi
Цитата(ViKo @ Apr 29 2011, 17:32) *
А вот assert как раз работает на этапе run-time, нет?

Да. Но когда определён макрос NDEBUG, как это полагается делать при сборке окончательной версии, все assert() пропадают.

Цитата(ViKo @ Apr 29 2011, 17:32) *
А проверять при компиляции - только #if ... #error. Правильно?

Нет, не только. Ещё assert_static().
Только возведение дробных чисел в дробную степень на стадии компиляции - это проблема.
prottoss
А если попробовать сделать так:
Код
static float pow_01_001(void)
{  
   return (pow(0.1, 0.01));
}

float func(float x)
{
     return (x*pow_01_001());
}
DevL
стадия компиляции это может быть забавно - как раз попалось ,
Магия шаблонов или вычисление факториала на стадии компиляции

pow это конечно другое , но было бы интересно пример с constant propagation
ReAl
Цитата(DevL @ Apr 30 2011, 00:36) *
pow это конечно другое , но было бы интересно пример с constant propagation
Просто pow() у него built-in, если это не отбить ключами -fno-builtin или -fno-builtin-pow
http://gcc.gnu.org/onlinedocs/gcc-4.6.0/gc...#Other-Builtins

А на built-in функции constant propagation распространяется естественнейшим образом.

Цитата(demiurg_spb @ Apr 29 2011, 11:32) *
--cpu Cortex-M3
...
Есть идеи куда копать?
В сторону Klen-овой сборки arm-gcc ? rolleyes.gif
demiurg_spb
Цитата(prottoss @ Apr 29 2011, 18:40) *
А если попробовать сделать так:
Код
static float pow_01_001(void)...
Попробовал - нет разницы.

Цитата(scifi @ Apr 29 2011, 18:23) *
Нет, не только. Ещё assert_static().
Я STATIC_ASSERT(...) регулярно применяю, и в этом случае тоже пришлось. Может кому пригодится:
CODE
/*
* ASSERTION - УТВЕРЖДЕНИЕ
*
* Example of usage:
* STATIC_ASSERT(sizeof(int) > 4); // produce error in ARM or X86 machine
*
*/

#ifndef _STATIC_ASSERT_H_
#define _STATIC_ASSERT_H_

#ifdef __cplusplus
template<bool> struct CompileTimeError;
template<> struct CompileTimeError<true> {};
# define STATIC_ASSERT(expr) (CompileTimeError<(expr) != 0>())
#else
# define MY_JOIN_3_H(A,B,C) A##B##C
# define MY_JOIN_3(A,B,C) MY_JOIN_3_H(A,B,C)
# define STATIC_ASSERT_H(expr) typedef int MY_JOIN_3(static_assert_,__LINE__,_h) [(expr) ? 1 : -1]
# define STATIC_ASSERT(expr) STATIC_ASSERT_H(expr)
#endif

#endif //_STATIC_ASSERT_H_

Цитата(ReAl @ Apr 30 2011, 03:05) *
В сторону Klen-овой сборки arm-gcc ? rolleyes.gif
Я бы и рад, но на новом месте работы keil и бастаsad.gif

2DevL: Да, шаблоны - вещь приятная и полезная, но проект без плюсов...
prottoss
Цитата(demiurg_spb @ Apr 30 2011, 15:27) *
Попробовал - нет разницы.
А если вообще попробовать static float pow_01_001(void) упрятать в другой юнит?

Или запихать в цикл do{...}while(0)
demiurg_spb
Всё по прежнему.
Всё это ИМХО шаманские танцы с бубном уже.
Если не пошло влоб, то тут уж...
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.