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

 
 
> Снова к вопросу о разбухании кода arm-gcc
glonium
сообщение May 30 2012, 06:22
Сообщение #1


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

Группа: Участник
Сообщений: 77
Регистрация: 27-05-11
Пользователь №: 65 303



Добрый день господа форумчане!
Настроил среду разработки Eclipse как сказано тут http://makesystem.net/?p=988
Использую toolchain Codebench Lite!
Написал простенький список (приложен ниже) и скомпилировал проект когда посмотрел на размер кода был немного обескуражен!
Размер кода стал равен 87384 Байт!
В оптимизаторе поставил генерировать отдельные секции и в линкере удалять неиспользуемые секции, но не помогает!
В чём тут может быть дело?

PS Может поменять компилятор, вернее версию??? Что то где-то слышал что помогает!
Вот только на какую менять???

Сообщение отредактировал glonium - May 30 2012, 06:17
Прикрепленные файлы
Прикрепленный файл  list.rar ( 1.64 килобайт ) Кол-во скачиваний: 21
 
Go to the top of the page
 
+Quote Post
2 страниц V   1 2 >  
Start new topic
Ответов (1 - 25)
Непомнящий Евген...
сообщение May 30 2012, 06:52
Сообщение #2


Знающий
****

Группа: Свой
Сообщений: 771
Регистрация: 16-07-07
Из: Волгодонск
Пользователь №: 29 153



Ну смотри - ты приложил хидер с шаблоном. Шаблон после компиляции любым компилятором занимает ровно 0 байт sm.gif Место занимают конкретные инстанцирования этого шаблона.

Так что чтобы что-то тебе сказать, надо посмотреть на все остальное - приложи компилябельный проект целиком.

#include "exception.h" намекает на использование исключений. Исключения требуют довольно жирного рантайма - может быть дело в этом.

У меня минимальный elf занимает порядка 100 байт или около того - int main() { while (1); } с отключенным стартовым кодом.

Если добавить стартовый код, размер станет несколько больше. Если добавить поддержку исключений - станет килобайт 60 или около того.
Go to the top of the page
 
+Quote Post
glonium
сообщение May 30 2012, 08:04
Сообщение #3


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

Группа: Участник
Сообщений: 77
Регистрация: 27-05-11
Пользователь №: 65 303



Прошу прошения что то не подумал выложить проект! Исключения самописанные!
Вот проект целиком
Прикрепленные файлы
Прикрепленный файл  first.rar ( 957.2 килобайт ) Кол-во скачиваний: 17
 
Go to the top of the page
 
+Quote Post
Непомнящий Евген...
сообщение May 30 2012, 08:09
Сообщение #4


Знающий
****

Группа: Свой
Сообщений: 771
Регистрация: 16-07-07
Из: Волгодонск
Пользователь №: 29 153



дык а map ты не пытался сгенерить? Сгенери, посмотри кто у тебя самый толстый...
Go to the top of the page
 
+Quote Post
glonium
сообщение May 30 2012, 09:12
Сообщение #5


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

Группа: Участник
Сообщений: 77
Регистрация: 27-05-11
Пользователь №: 65 303



Да сгенерил только ничего не понял из него в нём куча всего!

Да вы правы к сожалению всё дело в исключениях!
они в моём случае добавляют около 70 кб!
А есть ли способ обойти это или только отказом от исключений?

Да и поэкспериментировав я наткнулся на то что оператор new тоже много чего тянет за собой!
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение May 30 2012, 09:47
Сообщение #6


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Насчет исключений не подскажу, полагаю, что поддержка их зарыта глубоко в компиляторе и просто так переписать библиотеку не получится.
QUOTE (glonium @ May 30 2012, 12:12) *
Да и поэкспериментировав я наткнулся на то что оператор new тоже много чего тянет за собой!
Да, тянет. Используйте свой менеджер памяти, например вот этот.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
glonium
сообщение May 30 2012, 13:06
Сообщение #7


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

Группа: Участник
Сообщений: 77
Регистрация: 27-05-11
Пользователь №: 65 303



Спасибо за ответ! Интересное предложение. А со своим диспетчером памяти у меня механизм виртуальных функций будет работать, а так же dunamic_cast<>???
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение May 30 2012, 13:21
Сообщение #8


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



QUOTE (glonium @ May 30 2012, 16:06) *
А со своим диспетчером памяти у меня механизм виртуальных функций будет работать, а так же dynamic_cast<>???
Виртуальные функции работают (проверено, использую), за них конструктор отвечает. А он вызывается после выделения памяти оператором new(). А про dynamic_cast я только краем уха слышал, может кто-то другой подскажет. Хотя навряд ли она завязана на менеджер памяти - он лишь выделяет кусок памяти запрошенного размера. Если dynamic_cast работает с placement new(), то и с этим работать должен.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
glonium
сообщение Jun 1 2012, 13:58
Сообщение #9


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

Группа: Участник
Сообщений: 77
Регистрация: 27-05-11
Пользователь №: 65 303



Поэкспериментировав с перегрузкой операторов new и delete пришёл к интересным заключениям!
Вариант 1 :
Код
#include "stmlib/stm32f10x.h"
#include <stdlib.h>

void *operator new (size_t size)
{
    return malloc(size);
}
void operator delete (void *p)
{
    free(p);
    return;
}

int main (void)
{
    int *a=new int(10);
    while (1){};
    return 0;
}

Компилиться в 4 Кб с использованием стандартных free и malloc!
2 Случай
Код
/*
void *operator new (size_t size)
{
    return malloc(size);
}
void operator delete (void *p)
{
    free(p);
    return;
}
*/
int main (void)
{
    int *a=new int(10);
    while (1){};
    return 0;
}

Компилиться в 80Кб!
Почему такая разница? Вроде стандартный new и delete опирается на стандартные malloc и free!
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Jun 1 2012, 14:47
Сообщение #10


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



А если так:
CODE
#include <new>
.....
*/
int main (void)
{
    int *a=new(std::nothrow)  int(10);
    while (1){};
    return 0;
}



--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
glonium
сообщение Jun 1 2012, 15:00
Сообщение #11


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

Группа: Участник
Сообщений: 77
Регистрация: 27-05-11
Пользователь №: 65 303



Цитата
А если так:
CODE
#include <new>
.....
*/
int main (void)
{
int *a=new(std::nothrow) int(10);
while (1){};
return 0;
}

Так тоже порядка 80Кб!

Да и вообще у меня подозрение что в c++ другой аллокатор памяти потяжелее чем в с!
Go to the top of the page
 
+Quote Post
_Артём_
сообщение Jun 1 2012, 15:16
Сообщение #12


Гуру
******

Группа: Свой
Сообщений: 2 128
Регистрация: 21-05-06
Пользователь №: 17 322



Цитата(glonium @ Jun 1 2012, 18:00) *
Так тоже порядка 80Кб!

Да и вообще у меня подозрение что в c++ другой аллокатор памяти потяжелее чем в с!


glonium, вы не могли бы проект целиком выложить. Интересно бы посмотреть, а то у меня вообще не собирается.

P.S. И какой компилятор?.
Go to the top of the page
 
+Quote Post
glonium
сообщение Jun 1 2012, 15:45
Сообщение #13


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

Группа: Участник
Сообщений: 77
Регистрация: 27-05-11
Пользователь №: 65 303



Цитата
P.S. И какой компилятор?.

Использую CodeBench руководствовался это статьёй при установке IDE http://makesystem.net/?p=988

Цитата
glonium, вы не могли бы проект целиком выложить. Интересно бы посмотреть, а то у меня вообще не собирается.


Прикрепленные файлы
Прикрепленный файл  first.zip ( 912 килобайт ) Кол-во скачиваний: 18
 
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение Jun 1 2012, 16:13
Сообщение #14


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



Чтобы не подтягивались исключения, надо компилировать с ключом -fno-exceptions.
При использовании чисто виритуальных функций иногда подключаются исключения и с этим ключиком. В этом случае спасает вот этот файл. Просто добавьте его к своему проекту.


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
glonium
сообщение Jun 1 2012, 16:37
Сообщение #15


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

Группа: Участник
Сообщений: 77
Регистрация: 27-05-11
Пользователь №: 65 303



Цитата
Чтобы не подтягивались исключения, надо компилировать с ключом -fno-exceptions.

Поставил ключик -fno-exceptions все равно размер кода не уменьшается, при этом виртуальные функции не использую!

PS видать это вовсе не исключения так весят а аллокатор памяти!
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение Jun 1 2012, 17:38
Сообщение #16


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



Цитата(glonium @ Jun 1 2012, 22:37) *
PS видать это вовсе не исключения так весят а аллокатор памяти!

Посмотрите map-файл, и увидите, что это всё-таки исключения. К сожалению, ключик -fno-exceptions не всегда соблюдается.
Попробуйте объявить new/delete как
Код
void * operator new (size_t size, const std::nothrow_t&) throw()
{
...
}

void operator delete(void * pobject, const std::nothrow_t&) throw()
{
..
}

И добавьте всё же к своему проекту файл из моего предыдущего сообщения.


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
glonium
сообщение Jun 1 2012, 22:25
Сообщение #17


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

Группа: Участник
Сообщений: 77
Регистрация: 27-05-11
Пользователь №: 65 303



Цитата
Посмотрите map-файл, и увидите, что это всё-таки исключения.

Я если честно не до конца разобрался как пользоваться map и как от туда узнать что сколько весит (непонятные имена функций)
Подскажите пожалуйста где можно прочитать про map!
Заранее спасибо!
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение Jun 2 2012, 14:33
Сообщение #18


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



А чего там уметь-то? Смотрите, видите "eh_exception.o" - значит, исключения присутствуютsm.gif
Ну а так, там в самом начале есть строчка:
Archive member included because of file (symbol)
То есть, формат такой
подключенная_библиотека (имя_объекта_из_этой_библиотеки.o) имя_файла_из_за_которого_подключили_этот_библиотечный_объект (имя_функции_из_за_которой_подключили)

Попробуйте сделать, как я сказал в предыдущем сообщении, думаю, что поможет.
Кстати, не забудьте остальные варианты new/delete:
Код
void * operator new(size_t size){ return operator new(size, std::nothrow); }
void operator delete(void * pobject){ operator delete(pobject, std::nothrow); }
void * operator new[](size_t size){ return operator new(size, std::nothrow); }
void operator delete[](void * pobject){ operator delete[](pobject, std::nothrow); }
void * operator new[](size_t size, const std::nothrow_t&) throw(){ return operator new(size, std::nothrow); }
void operator delete[](void * pobject, const std::nothrow_t&) throw(){ operator delete(pobject, std::nothrow); }


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
glonium
сообщение Jun 8 2012, 12:12
Сообщение #19


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

Группа: Участник
Сообщений: 77
Регистрация: 27-05-11
Пользователь №: 65 303



Да очень жаль конечно что всё это весит много!
В проекте планировалось использовать dunamic_cast<> (RTTI) для реализации подобия интерфейсов.
Народ а может кто подсказать если я использую RTTI и throw то к программе добавляется кусок порядка 80кБ, есть ли гарантия что он не вырастет необоснованно? Т.е один раз приклеился и всё больше ничего не надо!
Go to the top of the page
 
+Quote Post
_Артём_
сообщение Jun 8 2012, 19:21
Сообщение #20


Гуру
******

Группа: Свой
Сообщений: 2 128
Регистрация: 21-05-06
Пользователь №: 17 322



Цитата(glonium @ Jun 8 2012, 15:12) *
В проекте планировалось использовать dunamic_cast<> (RTTI) для реализации подобия интерфейсов.

А что такого вам даёт RTTI?
Интерфейсы в С++ ведь реализуются с помощью абстрактных классов с наследованием. Этого недостаточно?
Go to the top of the page
 
+Quote Post
glonium
сообщение Jun 10 2012, 09:56
Сообщение #21


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

Группа: Участник
Сообщений: 77
Регистрация: 27-05-11
Пользователь №: 65 303



так то так но вот предположим у нас есть список объектов базоаого класса в виде указателей на них, при помощи dynamic_cast<*Iface> можно определить поддерживает ли данный инстанс интерфейс Iface и заодно преобразовать к классу интерфейса, если не поддерживает dynamic_cast вернёт NULL!

Конечно можно поступить и менее красиво, держать в классе флаги поддержки интерфейса и по их значениям кастовать!

Или ещё вариант но тоже менее красивый завести виртуальные функции которые кастуют к конкретному интерфейсу!
Go to the top of the page
 
+Quote Post
alx2
сообщение Jun 11 2012, 10:38
Сообщение #22


Местный
***

Группа: Участник
Сообщений: 340
Регистрация: 25-10-05
Из: Пермь, Россия
Пользователь №: 10 091



Цитата(glonium @ Jun 8 2012, 17:12) *
Народ а может кто подсказать если я использую RTTI и throw то к программе добавляется кусок порядка 80кБ, есть ли гарантия что он не вырастет необоснованно? Т.е один раз приклеился и всё больше ничего не надо!

Если Вы имеете в виду библиотечный код - то гарантия полная. Библиотечный модуль может быть загружен линкером только один раз.


--------------------
Всего наилучшего,
Alex Mogilnikov
Go to the top of the page
 
+Quote Post
neiver
сообщение Jun 11 2012, 11:52
Сообщение #23


Местный
***

Группа: Участник
Сообщений: 214
Регистрация: 22-03-10
Из: Саратов
Пользователь №: 56 123



Цитата(glonium @ Jun 10 2012, 13:56) *
так то так но вот предположим у нас есть список объектов базоаого класса в виде указателей на них, при помощи dynamic_cast<*Iface> можно определить поддерживает ли данный инстанс интерфейс Iface и заодно преобразовать к классу интерфейса, если не поддерживает dynamic_cast вернёт NULL!

Конечно можно поступить и менее красиво, держать в классе флаги поддержки интерфейса и по их значениям кастовать!

Или ещё вариант но тоже менее красивый завести виртуальные функции которые кастуют к конкретному интерфейсу!

"флаги поддержки интерфейса" в классе - это призанак "моей первой программы на С++", часто появляются, когда люди много писали на простом Си.
Опрос возможностей с помощью dynamic_cast - это уже "вторая программа на С++" - осознание недостаатков первой.
Вариант с виртуальными функциями чуть лучше, но всё равно опрос возможностей или попытка узнать конкретный тип объекта почти всегда являются признаками неудачного проектирования. Этот самый тип объекта просто не нужно терять, чтоб потом не нужно было его динамически узнавать. Единственное адекватное применение опроса типа или возможностей объекта, dynamic_cast в частности и RTTI вообще - это ИМХО разработка своей библиотеки сериализации.
Рекомендую по этому по этому вопросу почитать книжку: Стефан К. Дьюхэрст "Скользкие места С++". Там очень хорошо этот вопрос расписан.
Go to the top of the page
 
+Quote Post
glonium
сообщение Jun 16 2012, 17:13
Сообщение #24


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

Группа: Участник
Сообщений: 77
Регистрация: 27-05-11
Пользователь №: 65 303



Спасибо за книгу интересные моменты обсуждаются!
Интересная картина получается!!!
Чтобы избежать проблем со множественным наследованием используем интерфейсы костыльным методом,
реализация интерфейсов предпологает нисходящее преобразование типов (как быть иначе я пока не вижу, вернее как узнать поддерживает ли данный инстанс интерфейс или нет), что в свою очередь нежелательно!
Все методы корректного нисходящего преобразования это ошибка проектирования, а множественное наследование штука тоже не из хороших,
а как тогда быть? Ведь невозможно провести классификацию сложных объектов без множественного наследования или хотя бы интерфейсов!
Go to the top of the page
 
+Quote Post
neiver
сообщение Jun 16 2012, 20:02
Сообщение #25


Местный
***

Группа: Участник
Сообщений: 214
Регистрация: 22-03-10
Из: Саратов
Пользователь №: 56 123



Вот! Именно для этого есть принципы SOLID. Очень рекомендую.
Go to the top of the page
 
+Quote Post
glonium
сообщение Jun 21 2012, 06:26
Сообщение #26


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

Группа: Участник
Сообщений: 77
Регистрация: 27-05-11
Пользователь №: 65 303



Это конечно всё понятно принципы SOLID!
Вот только я не могу связать теорию с практикой, а именно пусть у нас есть список инстансов приведённых к базовому классу, есть базовый интерфейс в виде виртуальных функций, но каждый объект наследник базового класса обладает ведь по определению расширенным функционалом специфичным только ему, и как им воспользоваться следуя вышеприведённым принципам не понятно! Реализация механизма обработки событий тоже требует оператора switch только внутри каждого из наследников при обработке события! Прошу Вас подсказать как действовать в этой ситуации не нарушая принципов ООП?

Сообщение отредактировал glonium - Jun 21 2012, 19:08
Go to the top of the page
 
+Quote Post

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

 


RSS Текстовая версия Сейчас: 2nd August 2025 - 16:00
Рейтинг@Mail.ru


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