Вопросы по С/С++ (СИ)
- ПростоНуб
- Собутыльник Кота
- Сообщения: 2723
- Зарегистрирован: Пт сен 07, 2018 20:20:02
- Откуда: деревня в Тульской губернии
Re: Вопросы по С/С++ (СИ)
VladislavS, а я старый гентушник, и пересобирал GCC многократно. Именно с него и начинается перекомпиляция мира.
А проекты бывают разные. У меня может быть один проект, а там от МК до BI и мобильных приложений все в одном флаконе.
Eddy_Em, С не настолько универсален, как Вам кажется. Например, попробуйте на досуге на С поработать с большими объемами данных. А потом сравните, насколько быстреее и эфективней тоже самое делается на R/SQL/MDX/DAX.
И не надо мне говорить, что это не касается МК. Я только сегодня терабайт данных собранных МК анализировал - полмиллиарда строк в одной таблице!
А проекты бывают разные. У меня может быть один проект, а там от МК до BI и мобильных приложений все в одном флаконе.
Eddy_Em, С не настолько универсален, как Вам кажется. Например, попробуйте на досуге на С поработать с большими объемами данных. А потом сравните, насколько быстреее и эфективней тоже самое делается на R/SQL/MDX/DAX.
И не надо мне говорить, что это не касается МК. Я только сегодня терабайт данных собранных МК анализировал - полмиллиарда строк в одной таблице!
- Реклама
- ARV
- Ум, честь и совесть. И скромность.
- Сообщения: 18546
- Зарегистрирован: Чт дек 28, 2006 08:19:56
- Откуда: Новочеркасск
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
это именно та проблема, которая волнует практически всех любителей МК.ПростоНуб писал(а):Я только сегодня терабайт данных собранных МК анализировал - полмиллиарда строк в одной таблице!
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
- ПростоНуб
- Собутыльник Кота
- Сообщения: 2723
- Зарегистрирован: Пт сен 07, 2018 20:20:02
- Откуда: деревня в Тульской губернии
Re: Вопросы по С/С++ (СИ)
ARV, а может быть наоборот, Вы единственный, кто никогда не встречал МК в системах сбора данных? )))
Re: Вопросы по С/С++ (СИ)
[uquote="ПростоНуб",url="/forum/viewtopic.php?p=3706049#p3706049"]NStorm, если честно, не понял Вашу мысль. Если не формировать extern при включении этого заголовочного файла в остальные исходные тексты проекта, то компилятор выделит память под эту переменную в каждом объектном файле. И компоновщик отругается на дублирование имени внешней ссылки. А если в остальных файлах декларировать эту переменную, как extern (tentative definition), то сразу теряется смысл идеи - описывать переменную одной строкой один раз в одном месте.[/uquote]
extern - это declaration, а tentative definition это просто int var; На чисто C не ругнется, компоновщик потом соберет всё.
main.h:
main.c:
test.c:
Соберется без проблем. С чистым C. В плюсах такое не прохляет афаик.
Добавлено after 4 minutes 44 seconds:
Вот. main.c:
Выхлоп:
extern - это declaration, а tentative definition это просто int var; На чисто C не ругнется, компоновщик потом соберет всё.
main.h:
Код: Выделить всё
int zzz;Код: Выделить всё
#include "main.h"
extern void test();
int main(void) {
zzz = 111;
test();
}
Код: Выделить всё
#include "main.h"
void test() {
zzz = 123;
return;
}
Добавлено after 4 minutes 44 seconds:
Вот. main.c:
Код: Выделить всё
#include <stdio.h>
#include "main.h"
extern void test();
int main(void) {
zzz = 111;
printf("zzz = %d, zzz addr = %p.\n", zzz, &zzz);
test();
printf("zzz = %d, zzz addr = %p.\n", zzz, &zzz);
return 0;
}
Код: Выделить всё
gcc -Os -std=gnu11 -flto -Wall -c main.c -o main.o
gcc -Os -std=gnu11 -flto -Wall -c test.c -o test.o
gcc -Os -std=gnu11 -flto -Wall -o main main.o test.o
# ./main
zzz = 111, zzz addr = 0x60103c.
zzz = 123, zzz addr = 0x60103c.
- ПростоНуб
- Собутыльник Кота
- Сообщения: 2723
- Зарегистрирован: Пт сен 07, 2018 20:20:02
- Откуда: деревня в Тульской губернии
Re: Вопросы по С/С++ (СИ)
NStorm, на SDCC не проканало: "Multiple definition of ..."
А GCC собрал.
А GCC собрал.
- Реклама
- ARV
- Ум, честь и совесть. И скромность.
- Сообщения: 18546
- Зарегистрирован: Чт дек 28, 2006 08:19:56
- Откуда: Новочеркасск
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
я ожидал этого... и был сильно удивлен, когдаПростоНуб писал(а):Multiple definition of
чем больше я изучаю Си, тем больше утверждаюсь во мнении, что это крайне противоречивый и нелогичный язык. страдаю от этого неимоверно.ПростоНуб писал(а):GCC собрал
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
- VladislavS
- Собутыльник Кота
- Сообщения: 2562
- Зарегистрирован: Вт май 01, 2018 19:44:47
Re: Вопросы по С/С++ (СИ)
Ещё один повод переключить компилятор в режим С++.
- ARV
- Ум, честь и совесть. И скромность.
- Сообщения: 18546
- Зарегистрирован: Чт дек 28, 2006 08:19:56
- Откуда: Новочеркасск
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
Боюсь, от С++ я буду страдать ещё неимовернее 
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
- ПростоНуб
- Собутыльник Кота
- Сообщения: 2723
- Зарегистрирован: Пт сен 07, 2018 20:20:02
- Откуда: деревня в Тульской губернии
Re: Вопросы по С/С++ (СИ)
VladislavS, все нормально, раз такая шняга, то просто добавил в глобальный makefile опцию "-Xlinker --warn-common" для сборки GCC
Теперь хоть предупреждает о таком:
Теперь хоть предупреждает о таком:
Код: Выделить всё
test.o: warning: multiple common of `zzz'
main.o: warning: previous common is hereRe: Вопросы по С/С++ (СИ)
[uquote="NStorm",url="/forum/viewtopic.php?p=3706349#p3706349"]Вот. main.c:[/uquote]
Какой смысл брать два раза адрес переменной в main.c? Сделай функцию в test.c которая будет возвращать адрес переменной именно в том юните.
Какой смысл брать два раза адрес переменной в main.c? Сделай функцию в test.c которая будет возвращать адрес переменной именно в том юните.
- ПростоНуб
- Собутыльник Кота
- Сообщения: 2723
- Зарегистрирован: Пт сен 07, 2018 20:20:02
- Откуда: деревня в Тульской губернии
Re: Вопросы по С/С++ (СИ)
VladislavS, не идеализируйте C++. Без полноценных new/delete и обработки исключений от него толку мало, а размер кода больше. Особенно если пользоваться стандартной библиотекой. Например, почти любой контейнер для конкретного применения можно реализовать на C эффективней. В ущерб универсальности, само собой. Так что, если нет сотни килобайт оперативки и мегабайта флеша, C++ я избегаю.
Добавлено after 1 minute 2 seconds:
Reflector, это ни на что не повлияет. Объединение таких общих объявлений реализует компоновщик (ld).
[uquote="NStorm",url="/forum/viewtopic.php?p=3706349#p3706349"]компоновщик потом соберет всё.[/uquote]
Ну и засада!
test.c:
main.c:
Выхлоп:
Добавлено after 1 minute 2 seconds:
Reflector, это ни на что не повлияет. Объединение таких общих объявлений реализует компоновщик (ld).
Добавлено after 37 minutes 38 seconds:--warn-common
Warn when a common symbol is combined with another common symbol or with a symbol definition. Unix linkers allow this somewhat sloppy practise, but linkers on some other operating systems do not. This option allows you to find potential problems from combining global symbols. Unfortunately, some C libraries use this practise, so you may get some warnings about symbols in the libraries as well as in your programs.
There are three kinds of global symbols, illustrated here by C examples:
int i = 1;
A definition, which goes in the initialized data section of the output file.
extern int i;
An undefined reference, which does not allocate space. There must be either a definition or a common symbol for the variable somewhere.
int i;
A common symbol. If there are only (one or more) common symbols for a variable, it goes in the uninitialized data area of the output file. The linker merges multiple common symbols for the same variable into a single symbol. If they are of different sizes, it picks the largest size. The linker turns a common symbol into a declaration, if there is a definition of the same variable.
The --warn-common option can produce five kinds of warnings. Each warning consists of a pair of lines: the first describes the symbol just encountered, and the second describes the previous symbol encountered with the same name. One or both of the two symbols will be a common symbol.
1.Turning a common symbol into a reference, because there is already a definition for the symbol.
<file>(<section>): warning: common of `<symbol>'
overridden by definition
<file>(<section>): warning: defined here
2. Turning a common symbol into a reference, because a later definition for the symbol is encountered. This is the same as the previous case, except that the symbols are encountered in a different order.
<file>(<section>): warning: definition of `<symbol>'
overriding common
<file>(<section>): warning: common is here
3. Merging a common symbol with a previous same-sized common symbol.
<file>(<section>): warning: multiple common
of `<symbol>'
<file>(<section>): warning: previous common is here
4. Merging a common symbol with a previous larger common symbol.
<file>(<section>): warning: common of `<symbol>'
overridden by larger common
<file>(<section>): warning: larger common is here
5. Merging a common symbol with a previous smaller common symbol. This is the same as the previous case, except that the symbols are encountered in a different order.
<file>(<section>): warning: common of `<symbol>'
overriding smaller common
<file>(<section>): warning: smaller common is here
[uquote="NStorm",url="/forum/viewtopic.php?p=3706349#p3706349"]компоновщик потом соберет всё.[/uquote]
Ну и засада!
test.c:
Код: Выделить всё
int zzz;
void test() {
zzz = 123;
return;
}
Код: Выделить всё
#include <stdio.h>
float zzz;
extern void test();
int main(void) {
zzz = 111;
printf("zzz = %g, zzz addr = %p.\n", zzz, &zzz);
test();
printf("zzz = %g, zzz addr = %p.\n", zzz, &zzz);
return 0;
}
Код: Выделить всё
zzz = 111, zzz addr = 00407070.
zzz = 1.7236e-043, zzz addr = 00407070.
- VladislavS
- Собутыльник Кота
- Сообщения: 2562
- Зарегистрирован: Вт май 01, 2018 19:44:47
Re: Вопросы по С/С++ (СИ)
ПростоНуб, зачем для эмбедда пользоваться тем что жрёт память? Есть же много плюшек и без этого. В любом деле голову надо включать.
- ПростоНуб
- Собутыльник Кота
- Сообщения: 2723
- Зарегистрирован: Пт сен 07, 2018 20:20:02
- Откуда: деревня в Тульской губернии
Re: Вопросы по С/С++ (СИ)
VladislavS, вот я и не пользуюсь. А "плюшки и без этого" на мою производительность совершенно не влияют. Даже наоборот. C, нередко, лаконичней C++, а код формируемый компилятором - предсказуемей.
P.S. Естественно, например, на QT я писал не мало. Но не на МК )
То бишь, развесистая иерархическая структура классов удобней, чем большая плоская библиотека многочисленных функций. Ну куда же в МК с несколькими килобайтами памяти большую библиотеку пихать?
P.S. Естественно, например, на QT я писал не мало. Но не на МК )
То бишь, развесистая иерархическая структура классов удобней, чем большая плоская библиотека многочисленных функций. Ну куда же в МК с несколькими килобайтами памяти большую библиотеку пихать?
Последний раз редактировалось ПростоНуб Вт сен 24, 2019 11:25:31, всего редактировалось 1 раз.
Re: Вопросы по С/С++ (СИ)
[uquote="Reflector",url="/forum/viewtopic.php?p=3706394#p3706394"]Какой смысл брать два раза адрес переменной в main.c? Сделай функцию в test.c которая будет возвращать адрес переменной именно в том юните.[/uquote]
ПростоНуб, да, засада и правда при несовпадении типов. Даже не ругается при этом. Надо в проекты дописать "-Wl,--warn-common".
Код: Выделить всё
[main.c]: zzz = 111, zzz addr = 0x60103c.
[test.c]: zzz = 123, zzz addr = 0x60103c.
[main.c]: zzz = 123, zzz addr = 0x60103c.
Re: Вопросы по С/С++ (СИ)
[uquote="ПростоНуб",url="/forum/viewtopic.php?p=3706396#p3706396"]Reflector, это ни на что не повлияет. Объединение таких общих объявлений реализует компоновщик (ld).[/uquote]
В том примере адреса переменных всегда будут одинаковые, даже если переменную объявить как static и будет две разные копии, потому смысла в таком подходе никакого.
В том примере адреса переменных всегда будут одинаковые, даже если переменную объявить как static и будет две разные копии, потому смысла в таком подходе никакого.
В С++ эти не самые подходящие для эмбедда контейнеры по крайней мере есть и некоторые ими пользуются, значит это плюс. На С конечно можно написать более эффективные реализации, но на С++ это тоже можно сделать. Однако на плюсах я могу сделать шаблонный класс работающий с разными типа, могу на стадии компиляции проверить равен ли размер контейнера степени двойки и выбрать более эффективный алгоритм. Таким образом контейнеры на С++ проще в обращении, функциональнее и в среднем эффективнее, а если эффективность не важна, то они уже просто есть в стандартной библиотеке.Без полноценных new/delete и обработки исключений от него толку мало, а размер кода больше. Особенно если пользоваться стандартной библиотекой. Например, почти любой контейнер для конкретного применения можно реализовать на C эффективней. В ущерб универсальности, само собой. Так что, если нет сотни килобайт оперативки и мегабайта флеша, C++ я избегаю.
- ПростоНуб
- Собутыльник Кота
- Сообщения: 2723
- Зарегистрирован: Пт сен 07, 2018 20:20:02
- Откуда: деревня в Тульской губернии
Re: Вопросы по С/С++ (СИ)
[uquote="Reflector",url="/forum/viewtopic.php?p=3706473#p3706473"]На С конечно можно написать более эффективные реализации, но на С++ это тоже можно сделать.[/uquote]
И смысл, если трудозатраты на C даже меньше? Меньше кнопок на клавиатуре нажимать )
И смысл, если трудозатраты на C даже меньше? Меньше кнопок на клавиатуре нажимать )
А зачем, это на МК? Я, кстати, параметрический полиморфизм недолюбливаю. Уже не раз тратил уйму времени на ловлю баг с ним. Оно вроде бы и красиво, но когда выясняется, что один и тот же метод с разными типами объектами соврешает совершенно разные манипуляции, хочется удавить того, кто это написал )Reflector писал(а):на плюсах я могу сделать шаблонный класс работающий с разными типа
- VladislavS
- Собутыльник Кота
- Сообщения: 2562
- Зарегистрирован: Вт май 01, 2018 19:44:47
Re: Вопросы по С/С++ (СИ)
[uquote="ПростоНуб",url="/forum/viewtopic.php?p=3706495#p3706495"]А зачем, это на МК?[/uquote]Метапрограммирование это шаблоны. С++ библиотеки это в основном шаблоны. Да и просто с шаблонами удобно. Какой-либо порт в класс удобно как тип передавать, а это шаблон.
Re: Вопросы по С/С++ (СИ)
[uquote="ПростоНуб",url="/forum/viewtopic.php?p=3706495#p3706495"]И смысл, если трудозатраты на C даже меньше? Меньше кнопок на клавиатуре нажимать )[/uquote]
Возьмем простейший RingBuffer, на С обычно создают структуру и потом передает ее первым параметров в каждую функцию, на С++ по сути эти функции находятся внутри такой-же структуры/класса и лишний аргумент передавать не нужно, а сами функции там и там одинаковые, разве что на С будет конкретный тип, а на С++ какой-нибудь T. Соответственно и трудозатраты будут одинаковыми, но класс потом можно улучшить за счет проверок времени компиляции, которых в С просто нет, и сделать код боле эффективным.
Возьмем простейший RingBuffer, на С обычно создают структуру и потом передает ее первым параметров в каждую функцию, на С++ по сути эти функции находятся внутри такой-же структуры/класса и лишний аргумент передавать не нужно, а сами функции там и там одинаковые, разве что на С будет конкретный тип, а на С++ какой-нибудь T. Соответственно и трудозатраты будут одинаковыми, но класс потом можно улучшить за счет проверок времени компиляции, которых в С просто нет, и сделать код боле эффективным.
А чем таким мк принципиально отличается от ПК, чтобы все контейнеры там работали только с uint8_t? Даже USART может работать в 9-ти битном режиме или почему-бы в векторе не хранить указатели?Reflector писал(а):А зачем, это на МК?
- ПростоНуб
- Собутыльник Кота
- Сообщения: 2723
- Зарегистрирован: Пт сен 07, 2018 20:20:02
- Откуда: деревня в Тульской губернии
Re: Вопросы по С/С++ (СИ)
VladislavS, вот Вы объяснили все )))
Любой шаблон имеет смысл при его использовании, как минимум, более двух раз. Так в противном случае проще обойтись без него. А в рамках одной программы МК - подобые классы - редкость. Именно поэтому для тех же pdk1x, stm8, MCS-51 и т.п. поддержки C++ Вы вряд ли где найдете. Что только подтверждает сказанное мной выше. С позволяет писать более эффективный код, чем С++.
Чтобы не устраивать холивар, просто погуглите, например, о Торвальдсе и С++ )))
Добавлено after 32 minutes 47 seconds:
[uquote="Reflector",url="/forum/viewtopic.php?p=3706651#p3706651"]Возьмем простейший RingBuffer, на С обычно создают структуру и потом передает ее первым параметров в каждую функцию[/uquote]
Вы вообще о чем? В худшем случае, предается указатель на структуру. Пихать структуру в стек - это уж точно не для МК.
Обычно же, передается только код сообщения и, возможно, один-два аргумента к нему. Далее функция уже сама разбирается с ним через одну глобальную статическую развесистую структуру.
Любой шаблон имеет смысл при его использовании, как минимум, более двух раз. Так в противном случае проще обойтись без него. А в рамках одной программы МК - подобые классы - редкость. Именно поэтому для тех же pdk1x, stm8, MCS-51 и т.п. поддержки C++ Вы вряд ли где найдете. Что только подтверждает сказанное мной выше. С позволяет писать более эффективный код, чем С++.
Чтобы не устраивать холивар, просто погуглите, например, о Торвальдсе и С++ )))
Добавлено after 32 minutes 47 seconds:
[uquote="Reflector",url="/forum/viewtopic.php?p=3706651#p3706651"]Возьмем простейший RingBuffer, на С обычно создают структуру и потом передает ее первым параметров в каждую функцию[/uquote]
Вы вообще о чем? В худшем случае, предается указатель на структуру. Пихать структуру в стек - это уж точно не для МК.
Обычно же, передается только код сообщения и, возможно, один-два аргумента к нему. Далее функция уже сама разбирается с ним через одну глобальную статическую развесистую структуру.
Давайте так, когда Вам удастся написать проект несколько более сложный, чем мигание светодиодом, на PDK14, используя C++ и его парадигму, я сам пойду убеждать Торвальдса, что пришла пора в ядро Linux принимать код на C+++ )))Reflector писал(а):А чем таким мк принципиально отличается от ПК, чтобы все контейнеры там работали только с uint8_t?
- Eddy_Em
- Собутыльник Кота
- Сообщения: 2516
- Зарегистрирован: Пт июл 12, 2019 22:52:01
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
[uquote="ПростоНуб",url="/forum/viewtopic.php?p=3706277#p3706277"]Например, попробуйте на досуге на С поработать с большими объемами данных. А потом сравните, насколько быстреее и эфективней тоже самое делается на R/SQL/MDX/DAX.[/uquote]
Можно подумать, sqlite не на сях написан...
И да: SQL — штука для ширпотреба. Для конкретной узкой ниши обычно уникальный алгоритм значительно производительней будет! Я не зря всякую мелочевку храню в nodb в бинарном виде (плюс отдельный индекс-файл для ускорения поиска). SQL слишком жирный для таких штук.
Добавлено after 1 minute 58 seconds:
[uquote="ПростоНуб",url="/forum/viewtopic.php?p=3706354#p3706354"]NStorm, на SDCC не проканало: "Multiple definition of ..."
А GCC собрал.[/uquote]
К сожалению, под всякую 8-битную редкость вроде пиков или STM8 только sdcc есть. Я давно ругаюсь на него: ему до gcc очень далеко. Иной раз посмотришь, что там sdcc наделает, схватишься за голову, и начнешь вручную оптимизировать...
А насчет крестов, я ими баловался лет 18 назад. Жуткая дрянь. Их имеет смысл пользовать разве что в заковыристых GUI, а в реальной жизни они не нужны! Особенно современные кресты-17, где уже чуть ли не весь буст в стандарт включили... Ужас какой-то! Особенно, когда десятистраничный исходник 10 минут компиляется, пока все шаблоны развернутся... Не знаю, кому от этого хорошо, но лично я в шоке от такого подхода! Уже почти пхытон какой-то получается с конвертером в С!
Можно подумать, sqlite не на сях написан...
И да: SQL — штука для ширпотреба. Для конкретной узкой ниши обычно уникальный алгоритм значительно производительней будет! Я не зря всякую мелочевку храню в nodb в бинарном виде (плюс отдельный индекс-файл для ускорения поиска). SQL слишком жирный для таких штук.
Добавлено after 1 minute 58 seconds:
[uquote="ПростоНуб",url="/forum/viewtopic.php?p=3706354#p3706354"]NStorm, на SDCC не проканало: "Multiple definition of ..."
А GCC собрал.[/uquote]
К сожалению, под всякую 8-битную редкость вроде пиков или STM8 только sdcc есть. Я давно ругаюсь на него: ему до gcc очень далеко. Иной раз посмотришь, что там sdcc наделает, схватишься за голову, и начнешь вручную оптимизировать...
А насчет крестов, я ими баловался лет 18 назад. Жуткая дрянь. Их имеет смысл пользовать разве что в заковыристых GUI, а в реальной жизни они не нужны! Особенно современные кресты-17, где уже чуть ли не весь буст в стандарт включили... Ужас какой-то! Особенно, когда десятистраничный исходник 10 минут компиляется, пока все шаблоны развернутся... Не знаю, кому от этого хорошо, но лично я в шоке от такого подхода! Уже почти пхытон какой-то получается с конвертером в С!


