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

 
 
> Функция sprintf
aBoomest
сообщение Jul 4 2018, 09:41
Сообщение #1


Частый гость
**

Группа: Участник
Сообщений: 167
Регистрация: 24-12-08
Из: Россия
Пользователь №: 42 714



Добрый день.
Работаю на NXP MK66FN2M0xxx18.
При этом при использовании функции sprintf для вывода чисел с плавающей запятой, программа на этой функции вылетает. Убираешь %f (т.е. выводишь все кроме float'ов) - все работает.
Кто сталкивался с подобным?

На сайте IAR нашел следующее https://www.iar.com/support/tech-notes/gene...point-f-on-arm/
Правда думается, что не о том.


--------------------
C уважением!
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
Jenya7
сообщение Jul 7 2018, 06:05
Сообщение #2


Профессионал
*****

Группа: Участник
Сообщений: 1 778
Регистрация: 29-03-12
Пользователь №: 71 075



уверен там хардварный FPU. включите его
Код
#define CORTEX_M4_BLOCK  0xe000e000
#define CPACR *(unsigned long *)(CORTEX_M4_BLOCK + 0xd88)  // Co-processor Access Control

//__enable_FPU();  
CPACR |= (0xf << 20);   // enable access to FPU
а вообще sprintf монструозная функция для эмбедед. никогда не использовал ее.
Go to the top of the page
 
+Quote Post
jcxz
сообщение Jul 24 2018, 11:09
Сообщение #3


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(Jenya7 @ Jul 7 2018, 09:05) *
а вообще sprintf монструозная функция для эмбедед. никогда не использовал ее.

Поразительно - человек беспокоится о расходе стека printf()-ом, но при этом даже не задумываясь лепит кучу константных данных в ОЗУ (строки, массивы указателей на строки и т.п. - как видно из разных его сообщений на форуме). В местах где это ну совершенно не нужно. wacko.gif
Go to the top of the page
 
+Quote Post
Jenya7
сообщение Jul 24 2018, 11:23
Сообщение #4


Профессионал
*****

Группа: Участник
Сообщений: 1 778
Регистрация: 29-03-12
Пользователь №: 71 075



Цитата(jcxz @ Jul 24 2018, 16:09) *
Поразительно - человек беспокоится о расходе стека printf()-ом, но при этом даже не задумываясь лепит кучу константных данных в ОЗУ (строки, массивы указателей на строки и т.п. - как видно из разных его сообщений на форуме). В местах где это ну совершенно не нужно. wacko.gif


а что плохого если строки лежат во txt секции?
Go to the top of the page
 
+Quote Post
jcxz
сообщение Jul 24 2018, 11:46
Сообщение #5


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(Jenya7 @ Jul 24 2018, 14:23) *
а что плохого если строки лежат во txt секции?

В какой txt-секции? Так как Вы пишете, все Ваши строки и указатели на них лежат в ОЗУ + инициализирующие значения лежат во флешь.
А если передаёте в некую функцию строку типа: Func("си_не_знаю_пишу_как_попало") и эта Func объявлена как Func(char *), то такой вызов говорит компилятору до вызова функции создать переменную char t[] = "си_не_знаю_пишу_как_попало"; где-то в ОЗУ - или на стеке или в static памяти, проинициализировав её в runtime из константы char const ti[] = "си_не_знаю_пишу_как_попало"; во флешь.
Go to the top of the page
 
+Quote Post
scifi
сообщение Jul 24 2018, 11:52
Сообщение #6


Гуру
******

Группа: Свой
Сообщений: 3 020
Регистрация: 7-02-07
Пользователь №: 25 136



Цитата(jcxz @ Jul 24 2018, 14:46) *
А если передаёте в некую функцию строку типа: Func("си_не_знаю_пишу_как_попало") и эта Func объявлена как Func(char *), то такой вызов говорит компилятору до вызова функции создать переменную char t[] = "си_не_знаю_пишу_как_попало"; где-то в ОЗУ - или на стеке или в static памяти, проинициализировав её в runtime из константы char const ti[] = "си_не_знаю_пишу_как_попало"; во флешь.

Ну это уже совсем трэш, угар и содомия. Вот не при помню ни одного повода, по которому неявно создавалась бы строка в ОЗУ. И в данном случае точно нет.
Поправка: если возвращать из функции по значению структуру, содержащую строку, эта структура будет временно создана на стеке. Но это совсем другой случай, конечно.
Go to the top of the page
 
+Quote Post
jcxz
сообщение Jul 24 2018, 12:03
Сообщение #7


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(scifi @ Jul 24 2018, 14:52) *
Ну это уже совсем трэш, угар и содомия. Вот не при помню ни одного повода, по которому неявно создавалась бы строка в ОЗУ. И в данном случае точно нет.

попробуйте:
char t[] = "строка";
где будет создана t?
Go to the top of the page
 
+Quote Post
scifi
сообщение Jul 24 2018, 12:06
Сообщение #8


Гуру
******

Группа: Свой
Сообщений: 3 020
Регистрация: 7-02-07
Пользователь №: 25 136



Цитата(jcxz @ Jul 24 2018, 15:03) *
попробуйте:
char t[] = "строка";
где будет создана t?

Это явно созданная в ОЗУ строка, о чём "char t[]" недвусмысленно говорит. У вас в дивном примере чуть выше написано совсем иначе.
Go to the top of the page
 
+Quote Post
jcxz
сообщение Jul 24 2018, 12:21
Сообщение #9


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(scifi @ Jul 24 2018, 15:06) *
Это явно созданная в ОЗУ строка, о чём "char t[]" недвусмысленно говорит. У вас в дивном примере чуть выше написано совсем иначе.

Ну так если аргумент функции описан как char *, то эта функция внутри имеет право выполнять запись по такому указателю. А значит компилятор не должен позволять передавать туда указатели на константные объекты. Разве не так?
Go to the top of the page
 
+Quote Post
scifi
сообщение Jul 24 2018, 12:26
Сообщение #10


Гуру
******

Группа: Свой
Сообщений: 3 020
Регистрация: 7-02-07
Пользователь №: 25 136



Цитата(jcxz @ Jul 24 2018, 15:21) *
Ну так если аргумент функции описан как char *, то эта функция внутри имеет право выполнять запись по такому указателю. А значит компилятор не должен позволять передавать туда указатели на константные объекты. Разве не так?

Нет, не так. Явным приведением типа можно отсечь от указателя const, и компилятор не пикнет. Копию в ОЗУ точно не будет создавать.
В порядке ликбеза: объявление переменной и список аргументов функции - это совсем разные штуки. Какое-то совпадение в семантике есть, но есть и кардинальные различия.
Go to the top of the page
 
+Quote Post
jcxz
сообщение Jul 24 2018, 13:49
Сообщение #11


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(scifi @ Jul 24 2018, 15:26) *
Нет, не так. Явным приведением типа можно отсечь от указателя const, и компилятор не пикнет. Копию в ОЗУ точно не будет создавать.

Ну я вообще-то говорю не про явное приведение типа.
А когда вообще без приведения типа функции, принимающей указатель на переменную, передаётся константа.
Явным приведением типа программист просто говорит, что в данном конкретном случае здесь передаётся "не то что можно ожидать по типу объявленного символического имени, а нечто другое".
Если функция использует принятый указатель только для операций чтения, то при объявлении такой функции надо этому указателю (аргументу) назначать модификатор const. Частный случай - член-функция класса, использующая члены класса только на чтение (и вызывающая только const член-функции класса) - тоже должна объявляться с модификатором const.
Если функция использует принятый аргумент-указатель и для операций записи, то тогда нужно описывать без слова const.
И компилятор, при передаче аргумента такой фукции, будет проверять чтобы const-указатели не передавались в не-const аргументы функций.

Цитата(VladislavS @ Jul 24 2018, 16:11) *
Вы правы. У меня в проекте вся менюшка выполнена в стиле lcd.Printx(0, " си_не_знаю_пишу_как_попало ");, где void Printx(uint8_t x,char *s);. Заглядываем в map по модулю меню.

Значит Ваш компилятор в этом случае не проверяет соответствие типов передаваемых данных и аргументов функции. И плохо. Это его недостаток.
Но это не значит что все компиляторы так делают.

Цитата(scifi @ Jul 24 2018, 16:04) *
Это очевидное заблуждение.

Почему?
В чём разница между:
char t[] = "XXXX";
и
void Func(char *)
?
И первом случае Вы говорите компилятору, что хотите иметь переменную (с начальным значением), а значит - хотите иметь возможность записи в неё. И во-втором случае говорите ему, что функция Func() хочет иметь возможность записи в принимаемый ею аргумент (т.е. - она принимает указатель на переменную). В чём принципиальная разница?
Go to the top of the page
 
+Quote Post
scifi
сообщение Jul 24 2018, 14:23
Сообщение #12


Гуру
******

Группа: Свой
Сообщений: 3 020
Регистрация: 7-02-07
Пользователь №: 25 136



Цитата(jcxz @ Jul 24 2018, 16:49) *
Значит Ваш компилятор в этом случае не проверяет соответствие типов передаваемых данных и аргументов функции. И плохо. Это его недостаток.

На самом деле типы соответствуют. Строковая константа имеет тип char[] без всяких const (сюрприз!), поэтому всё нормально. Это в C так, этот курьёз оставили, предположительно, из-за того, что к моменту изобретения const уже настрогали кучу кода, ломать его не хотелось. В то же время менять эту строку нельзя, поэтому компилятор мог бы предупреждать, но не по причине несоответствия типов, а по смыслу. В C++ всё проще: строка таки имеет тип const char[].

Цитата(jcxz @ Jul 24 2018, 16:49) *
Почему?

Вообще в данном случае ничто не запрещает компилятору создать копию строки в ОЗУ перед вызовом функции. Просто он этого не делает (и хорошо, зачем лишнюю работу делать?). Предлагаю собрать небольшой пример и заглянуть в листинг дизассемблера.
Go to the top of the page
 
+Quote Post
jcxz
сообщение Jul 25 2018, 06:03
Сообщение #13


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(scifi @ Jul 24 2018, 17:23) *
Вообще в данном случае ничто не запрещает компилятору создать копию строки в ОЗУ перед вызовом функции. Просто он этого не делает (и хорошо, зачем лишнюю работу делать?).

Хотя-бы потому, что это - идеологически было бы правильно.
Имхо: если функция только читает данные из переданного ей указателя - объявляй такой указатель с const, если и пишет - без const. А дальше - компилятор должен проверить соответствие типов и предупредить об ошибке. Что является только плюсом в отладке и уменьшении багов. Ну или автоматом устранить её, создав временный не-const объект на стеке или в static памяти. Ещё б желательно чтобы первое или второе поведение - определялось ключом компилятора.
А то, что почти все быдлокодеры будут писать без const и передавать туда константы - так это их проблемы.

Цитата(scifi @ Jul 24 2018, 17:23) *
Предлагаю собрать небольшой пример и заглянуть в листинг дизассемблера.

PS: Я уже проверял. Для IAR.
Go to the top of the page
 
+Quote Post
scifi
сообщение Jul 25 2018, 07:05
Сообщение #14


Гуру
******

Группа: Свой
Сообщений: 3 020
Регистрация: 7-02-07
Пользователь №: 25 136



Цитата(jcxz @ Jul 25 2018, 09:03) *
Хотя-бы потому, что это - идеологически было бы правильно.

Идеология - штука субъективная. У нас гласность, свобода совести и плюрализм мнений.
Я довольно хорошо изучил язык Си, и мне он кажется вполне логичным и непротиворечивым. Есть там спорные моменты, но для них есть понятные обоснования, с которыми несложно согласиться. Обсуждаемый момент к спорным не могу отнести.
Go to the top of the page
 
+Quote Post
jcxz
сообщение Jul 25 2018, 07:38
Сообщение #15


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(scifi @ Jul 25 2018, 10:05) *
Я довольно хорошо изучил язык Си, и мне он кажется вполне логичным и непротиворечивым.

Что-ж тут логичного, если char const t[] = "..."; Func(char *); Func(t); - вызывает ошибку, а Func("..."); - не вызывает?
Но при этом 2-й вариант хоть и компилируется, но может приводить к неработоспособному коду.
Хотя и в том и в другом случае данные одного и того же типа char const []. И даже более того - компилятор (линкёр?) могут объединить эти две константы в один объект в памяти.
Go to the top of the page
 
+Quote Post

Сообщений в этой теме
- aBoomest   Функция sprintf   Jul 4 2018, 09:41
- - jcxz   Цитата(aBoomest @ Jul 4 2018, 12:41) При ...   Jul 4 2018, 09:55
|- - megajohn   Цитата(jcxz @ Jul 4 2018, 13:55) Вангую и...   Jul 4 2018, 10:34
|- - scifi   Цитата(megajohn @ Jul 4 2018, 13:34) либо...   Jul 4 2018, 10:42
- - aBoomest   1. Операционок нет, для прерываний контекст сохран...   Jul 4 2018, 10:49
|- - scifi   Цитата(aBoomest @ Jul 4 2018, 13:49) Стэк...   Jul 4 2018, 11:13
|- - jcxz   Цитата(scifi @ Jul 4 2018, 14:13) Кстати,...   Jul 4 2018, 11:28
|- - demiurg_spb   Может банальное переполнение буфера? HINT: Попробу...   Jul 4 2018, 12:36
|- - scifi   Цитата(demiurg_spb @ Jul 4 2018, 15:36) М...   Jul 4 2018, 12:56
- - aBoomest   Цитата(scifi @ Jul 4 2018, 14:13) Именно....   Jul 5 2018, 19:29
|- - jcxz   Цитата(aBoomest @ Jul 5 2018, 22:29) Уваж...   Jul 6 2018, 08:50
|- - Arlleex   Цитата(Jenya7 @ Jul 24 2018, 15:23) а что...   Jul 24 2018, 11:40
|- - Сергей Борщ   QUOTE (scifi @ Jul 24 2018, 15:26) Нет, н...   Jul 24 2018, 12:54
||- - scifi   Цитата(jcxz @ Jul 25 2018, 10:38) Но при ...   Jul 25 2018, 08:25
||- - jcxz   Цитата(scifi @ Jul 25 2018, 11:25) Компил...   Jul 25 2018, 10:18
|- - VladislavS   Цитата(jcxz @ Jul 24 2018, 16:49) Значит ...   Jul 25 2018, 11:13
|- - Arlleex   Цитата(VladislavS @ Jul 25 2018, 15:13) В...   Jul 25 2018, 11:41
|- - jcxz   Цитата(VladislavS @ Jul 25 2018, 14:13) О...   Jul 25 2018, 11:46
- - aBoomest   Цитата(Jenya7 @ Jul 7 2018, 09:05) а вооб...   Jul 21 2018, 09:57
|- - Arlleex   Цитата(aBoomest @ Jul 21 2018, 12:57) Как...   Jul 21 2018, 11:10
|- - thermit   Цитата(aBoomest @ Jul 21 2018, 12:57) Как...   Jul 21 2018, 11:57
|- - Jenya7   Цитата(aBoomest @ Jul 21 2018, 14:57) Как...   Jul 24 2018, 09:14
- - Jenya7   я создам отдельную тему в В помощь начинающему ...   Jul 24 2018, 12:14
- - scifi   Цитата(Сергей Борщ @ Jul 24 2018, 15:54) ...   Jul 24 2018, 13:04
|- - VladislavS   Цитата(scifi @ Jul 24 2018, 16:04) Это оч...   Jul 24 2018, 13:11
- - VladislavS   Ещё как ругается. Если в Print(char *s); передать ...   Jul 25 2018, 11:51
|- - jcxz   Цитата(VladislavS @ Jul 25 2018, 14:51) Е...   Jul 25 2018, 12:16
|- - VladislavS   Цитата(jcxz @ Jul 25 2018, 15:16) Как Вы ...   Jul 25 2018, 12:24
- - scifi   Цитата(scifi @ Jul 25 2018, 11:25) Компил...   Jul 25 2018, 12:27
- - VladislavS   Цитата(scifi @ Jul 25 2018, 15:27) Очевид...   Jul 25 2018, 12:30
- - jcxz   Цитата(scifi @ Jul 25 2018, 15:27) Очевид...   Jul 25 2018, 15:42


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

 


RSS Текстовая версия Сейчас: 22nd June 2025 - 07:48
Рейтинг@Mail.ru


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