|
Функция sprintf |
|
|
|
Jul 24 2018, 14:23
|
Гуру
Группа: Свой
Сообщений: 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) Почему? Вообще в данном случае ничто не запрещает компилятору создать копию строки в ОЗУ перед вызовом функции. Просто он этого не делает (и хорошо, зачем лишнюю работу делать?). Предлагаю собрать небольшой пример и заглянуть в листинг дизассемблера.
|
|
|
|
|
Jul 25 2018, 06:03
|
Гуру
Группа: Свой
Сообщений: 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.
|
|
|
|
|
Jul 25 2018, 07:38
|
Гуру
Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713
|
Цитата(scifi @ Jul 25 2018, 10:05) Я довольно хорошо изучил язык Си, и мне он кажется вполне логичным и непротиворечивым. Что-ж тут логичного, если char const t[] = "..."; Func(char *); Func(t); - вызывает ошибку, а Func("..."); - не вызывает? Но при этом 2-й вариант хоть и компилируется, но может приводить к неработоспособному коду. Хотя и в том и в другом случае данные одного и того же типа char const []. И даже более того - компилятор (линкёр?) могут объединить эти две константы в один объект в памяти.
|
|
|
|
|
Jul 25 2018, 11:13
|
Местный
Группа: Свой
Сообщений: 475
Регистрация: 14-04-05
Из: Москва
Пользователь №: 4 140
|
Цитата(jcxz @ Jul 24 2018, 16:49) Значит Ваш компилятор в этом случае не проверяет соответствие типов передаваемых данных и аргументов функции. И плохо. Это его недостаток. Чего это он мой? Забери его себе Цитата(jcxz @ Jul 24 2018, 16:49) Но это не значит что все компиляторы так делают. GCC и IAR компилят одинаково. Какой ещё эталон нужен? Они передают в функцию const char* и если внутри работать как с char *, то матерятся. Код void Printx(const uint8_t x,const char *s) { const char *c; Goto(x); if (!(c=s)) return; while (*c) { WriteData(codepage[(uint8_t)*c]); c++; } } Вот в IAR AVR, с его кривой памятью, можно управлять процессом, кстати.
|
|
|
|
|
Jul 25 2018, 11:46
|
Гуру
Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713
|
Цитата(VladislavS @ Jul 25 2018, 14:13) Они передают в функцию const char* и если внутри работать как с char *, то матерятся. Вы не поняли. Разговор о случае если аргумент функции - char *, а передаваемое значение: Func("xxx") (char const *). То компилятор не ругается. А по уму должен бы. См. посты выше и https://electronix.ru/forum/index.php?showt...t&p=1574877
|
|
|
|
|
Jul 25 2018, 11:51
|
Местный
Группа: Свой
Сообщений: 475
Регистрация: 14-04-05
Из: Москва
Пользователь №: 4 140
|
Ещё как ругается. Если в Print(char *s); передать Print(" ");, то много нового о себе от компилятора узнаете. Ругается, правда, только варнингом. Как и GCC
В IAR это звучит как Код Warning[Pe2464]: conversion from a string literal to "char *" is deprecated Menu.cpp 54
|
|
|
|
|
Jul 25 2018, 12:24
|
Местный
Группа: Свой
Сообщений: 475
Регистрация: 14-04-05
Из: Москва
Пользователь №: 4 140
|
Цитата(jcxz @ Jul 25 2018, 15:16) Как Вы добились сего??? Версия IAR? какие ключи компиляции? Перепроверил ещё раз. 8.22.2 выдаёт варнинг, и 8.30.1 соответственно тоже. Младше у меня нет. Проект С++ с настройками по умолчанию.
|
|
|
|
|
Jul 25 2018, 12:27
|
Гуру
Группа: Свой
Сообщений: 3 020
Регистрация: 7-02-07
Пользователь №: 25 136
|
Цитата(scifi @ Jul 25 2018, 11:25) Компилируйте в режиме C++, ни в чём себе не отказывайте Цитата(jcxz @ Jul 25 2018, 15:16) Как Вы добились сего??? Версия IAR? какие ключи компиляции? Цитата(VladislavS @ Jul 25 2018, 15:24) Проект С++ с настройками по умолчанию. Цитата(jcxz @ Jul 25 2018, 13:18) И...? У меня и так C++. Очевидно, у вас таки не включен режим С++
|
|
|
|
|
Jul 25 2018, 15:42
|
Гуру
Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713
|
Цитата(scifi @ Jul 25 2018, 15:27) Очевидно, у вас таки не включен режим С++
ку? Расширение си-файлов тоже: .cpp. Без скриншота поверите? Цитата(VladislavS @ Jul 25 2018, 15:24) Перепроверил ещё раз. 8.22.2 выдаёт варнинг, и 8.30.1 соответственно тоже. Младше у меня нет. Проект С++ с настройками по умолчанию. Ясно. У меня 7.80.4. Есть ещё 8.20 - завтра может проверю. А всё что выше 8.22 - ставить не рискую. Почему - тема была тут: https://electronix.ru/forum/index.php?showt...=147939&hl=
|
|
|
|
2 чел. читают эту тему (гостей: 2, скрытых пользователей: 0)
Пользователей: 0
|
|
|