Модераторы: bsa

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Связывание нескольких .cpp компилятором, Хранение функций во внешнем файле 
V
    Опции темы
yorm
Дата 20.1.2008, 11:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 15
Регистрация: 1.10.2006

Репутация: нет
Всего: нет



Здравствуйте

Начал изучение c++, поэтому в специфичной терминологии еще плаваю. Помогите, пожалуйста, разобраться:

Хотелось функции хранить в отдельном файле и в основной подгружать только необходимые. Решил следующим образом

main.cpp - основной файл
Код

#include <iostream.h>

extern int test1();

extern char test4[];
extern int test5;

int main() {
    cout << "int test1(): " << test1() << endl;
    cout << "char test4[]: " << test4 << endl;
    cout << "int test5: " << test5 << endl;
    return 0;
}


func.cpp - здесь хранятся вызываемые функции
Код

int test1() {
    return 111;
}

int test2() {
    return 112;
}

char test3() {
    return 's';
}


vars.cpp - здесь хранятся переменные
Код

char test4[] = "test1";
int test5 = 11;


для компиляции использовал Borland C++ 5.6 for Win32 компилятор (из дистрибутива Borland C++ Builder)
bcc32 main.cpp func.cpp vars.cpp

А теперь, собственно, вопрос:
1. Действительно ли при компиляции в результирующий main.exe добавились только extern int test1(); extern char test4[]; extern int test5; или остальные функции и переменные из внешних файлов тоже там присутствуют?
2. При компиляции корневым (начальным) указывается первый .cpp в строке или порядок не важен?
3. Правильный ли способ я использую или можно каким-то другим образом хранить функции в отдельном файле и включать только необходимые? (#include, насколько я понял, включает файл целиком?)


PM MAIL   Вверх
MAKCim
Дата 20.1.2008, 11:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


Профиль
Группа: Экс. модератор
Сообщений: 5644
Регистрация: 10.12.2005
Где: Менск, РБ

Репутация: 2
Всего: 207



Цитата(yorm @  20.1.2008,  11:25 Найти цитируемый пост)
Действительно ли при компиляции в результирующий main.exe добавились только extern int test1(); extern char test4[]; extern int test5; или остальные функции и переменные из внешних файлов тоже там присутствуют?

не определено однозначно
хотя конкретно для BC можно узнать наверняка
Цитата(yorm @  20.1.2008,  11:25 Найти цитируемый пост)
При компиляции корневым (начальным) указывается первый .cpp в строке или порядок не важен?

не важен
Цитата(yorm @  20.1.2008,  11:25 Найти цитируемый пост)
Правильный ли способ я использую или можно каким-то другим образом хранить функции в отдельном файле и включать только необходимые? (#include, насколько я понял, включает файл целиком?)

extern-ы принято помещать в .h файл


--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
archimed7592
Дата 20.1.2008, 11:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Архимед
****


Профиль
Группа: Завсегдатай
Сообщений: 2531
Регистрация: 12.6.2004
Где: Moscow

Репутация: 6
Всего: 93



Статические переменные с внешним связыванием(т.е. как у тебя) будут включены обязательно. По крайней мере, по Стандарту.


--------------------
If you have an apple and I have an apple and we exchange apples then you and I will still each have one apple. But if you have an idea and I have an idea and we exchange these ideas, then each of us will have two ideas.
© George Bernard Shaw
PM Jabber   Вверх
yorm
Дата 20.1.2008, 13:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 15
Регистрация: 1.10.2006

Репутация: нет
Всего: нет



Цитата(archimed7592 @  20.1.2008,  11:44 Найти цитируемый пост)
Статические переменные с внешним связыванием(т.е. как у тебя) будут включены обязательно. По крайней мере, по Стандарту.

Это понятно. Интересовало - будут ли включены функции test2() и test3 из func.cpp. Сейчас посмотрел exe-шник, вроде нигде не присутствуют

Цитата(MAKCim @  20.1.2008,  11:41 Найти цитируемый пост)
extern-ы принято помещать в .h файл 

Понял. Т.е.
func.h
Код

extern char test4[];
extern int test5;

main.h
Код

#include <iostream.h>
#include "func.h"
extern int test1();

int main() {
    cout << "int test1(): " << test1() << endl;
    cout << "char test1[]: " << test4 << endl;
    cout << "int test5[]: " << test5 << endl;
    return 0;
}

*.h - это интерфейс, который должен быть реализован в одном из скомпилированных файлов, к которому он подключен?

PM MAIL   Вверх
MAKCim
Дата 20.1.2008, 13:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


Профиль
Группа: Экс. модератор
Сообщений: 5644
Регистрация: 10.12.2005
Где: Менск, РБ

Репутация: 2
Всего: 207



yorm, 
в .h файле не должно быть (кроме случаев, когда ты знаешь, что делаешь) определений, только объявления
в твоем случае надо делать так
Код

// def.h

extern char test4[];
extern int test5;
extern int test1();

Код

// main.cpp

#include <iostream.h>
#include "def.h"

int main() {
    cout << "int test1(): " << test1() << endl;
    cout << "char test1[]: " << test4 << endl;
    cout << "int test5[]: " << test5 << endl;
    return 0;
}



--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
yorm
Дата 20.1.2008, 14:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 15
Регистрация: 1.10.2006

Репутация: нет
Всего: нет



Спасибо за консультацию!
PM MAIL   Вверх
archimed7592
Дата 20.1.2008, 15:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Архимед
****


Профиль
Группа: Завсегдатай
Сообщений: 2531
Регистрация: 12.6.2004
Где: Moscow

Репутация: 6
Всего: 93



Цитата(yorm @  20.1.2008,  13:27 Найти цитируемый пост)
Интересовало - будут ли включены функции test2() и test3 из func.cpp.

Зависит от уровня интелекта компоновщика. Может выбросить все ненужные ф-ции, может не выбросить... и это не будет зависеть от того, в отдельном модуле они находятся или нет(хотя, не исключено, что линкер настолько туп, что умеет выбрасывать из итогового файла только модули целиком).


--------------------
If you have an apple and I have an apple and we exchange apples then you and I will still each have one apple. But if you have an idea and I have an idea and we exchange these ideas, then each of us will have two ideas.
© George Bernard Shaw
PM Jabber   Вверх
MAKCim
Дата 20.1.2008, 18:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


Профиль
Группа: Экс. модератор
Сообщений: 5644
Регистрация: 10.12.2005
Где: Менск, РБ

Репутация: 2
Всего: 207



Цитата(archimed7592 @  20.1.2008,  15:50 Найти цитируемый пост)
хотя, не исключено, что линкер настолько туп, что умеет выбрасывать из итогового файла только модули целиком

выходит, что LD туп  smile 
не, на самом деле это довольно нетривиальная задача


--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
archimed7592
Дата 20.1.2008, 18:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Архимед
****


Профиль
Группа: Завсегдатай
Сообщений: 2531
Регистрация: 12.6.2004
Где: Moscow

Репутация: 6
Всего: 93



А в чём нетривиальность заключается? 0_о 


--------------------
If you have an apple and I have an apple and we exchange apples then you and I will still each have one apple. But if you have an idea and I have an idea and we exchange these ideas, then each of us will have two ideas.
© George Bernard Shaw
PM Jabber   Вверх
MAKCim
Дата 20.1.2008, 19:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


Профиль
Группа: Экс. модератор
Сообщений: 5644
Регистрация: 10.12.2005
Где: Менск, РБ

Репутация: 2
Всего: 207



archimed7592, 
скажем так, не нетривиальная, а доволно сложная  smile 
представь себе набор объектных файлов, которые поступают на вход компоновщику
каков алгоритм его работы?
в случае LD в качестве алгоритма выступает скрипт, который ставит в соответствие секциям входных объектных файлов секциии выходного
если не смотреть на то, что на самом деле используется, а что нет, то все крайне просто: берется секция входного объектного файла и помещается по определенному смещению в выходной
если смотреть на факт использования, то для каждой секции входного объектного файла нужно найти символы, которые определены в ней
для каждого такого символа нужно находить все релокации в других объектных файлах, которые ссылаются на этот символ
если эти другие объектные файлы не являются контейнером для main(), то необходимо определить контекст релокации, т. е в контексте определения какого символа находится релокация и, определив, продолжить процесс рекурсивно
причем есть вероятность того, что этот процесс породит бесконечную рекурсию
кроме того, не факт, что символ, на который есть релокация в другом символе, определенном в модуле с символом main, действительно не используется


--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
archimed7592
Дата 20.1.2008, 19:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Архимед
****


Профиль
Группа: Завсегдатай
Сообщений: 2531
Регистрация: 12.6.2004
Где: Moscow

Репутация: 6
Всего: 93



Цитата(MAKCim @  20.1.2008,  19:11 Найти цитируемый пост)
причем есть вероятность того, что этот процесс породит бесконечную рекурсию

Цикличность графа отслеживать не судьба? smile

На самом деле, если, в придачу, компилятор будет отслеживать зависимости(те что он может отследить - т.е. в пределах объектника) и вкладывать эту информацию в объектник, то компоновщику нужно будет решить элементарную задачу выявления зависимостей, которая, на самом деле, тривиальна smile.


--------------------
If you have an apple and I have an apple and we exchange apples then you and I will still each have one apple. But if you have an idea and I have an idea and we exchange these ideas, then each of us will have two ideas.
© George Bernard Shaw
PM Jabber   Вверх
MAKCim
Дата 20.1.2008, 22:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


Профиль
Группа: Экс. модератор
Сообщений: 5644
Регистрация: 10.12.2005
Где: Менск, РБ

Репутация: 2
Всего: 207



Цитата(archimed7592 @  20.1.2008,  19:31 Найти цитируемый пост)
и вкладывать эту информацию в объектник

не забываем, что форматы файлов специфицированы и просто так добавить какую-то информацию туда нельзя  smile
кроме того, вот пример ситуации, при которой компоновщик обламывается
Код

/* main.c */
extern int foo();

int main() {
    return foo();
}
 
Код

/* functions.S */

.text
some:
    nop
    nop
    ret
.globl some
1:
    call    routine
    ret
foo:
    jmp   1b
.globl foo

Код

/* routine.S */

.text
routine:
    xorl    %eax, %eax
    ret
.globl routine

вообщем, есть три файла: main.c, functions.S, routine.S
при компиляции получаем 3 объектных файла: main.o, functions.o, routine.o
подаем их на вход компоновщику и...
попробуй догадаться, почему конечная программа не будет работать, если компоновщик будет отслеживать зависимости по приведенному выше алгоритму  smile

Добавлено через 2 минуты и 47 секунд
Цитата(archimed7592 @  20.1.2008,  19:31 Найти цитируемый пост)
На самом деле, если, в придачу, компилятор будет отслеживать зависимости(те что он может отследить - т.е. в пределах объектника)

как быть с callback-функциями?
не все так просто


--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
warmonger_
Дата 20.1.2008, 23:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 155
Регистрация: 7.7.2007
Где: г. Киев

Репутация: 1
Всего: 3



Цитата(yorm @  20.1.2008,  13:27 Найти цитируемый пост)
будут ли включены функции test2() и test3 из func.cpp

что бы этого точно не было, нужно пользоваться пространством имен

Это сообщение отредактировал(а) warmonger_ - 20.1.2008, 23:14
--------------------
Make everything as simple as possible, but not simpler.Albert Einstein
PM MAIL   Вверх
JackYF
Дата 20.1.2008, 23:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


полуавантюрист
****


Профиль
Группа: Участник
Сообщений: 5814
Регистрация: 28.8.2004
Где: страна тысячи озё р

Репутация: 6
Всего: 162



Цитата(warmonger_ @  20.1.2008,  22:13 Найти цитируемый пост)
нужно пользоваться пространством имен

А, по-моему, это чисто логическое отделение функций/классов, и линковищку на пространства имён с глубокой высокой башни.
Поправьте меня, если я не прав.



--------------------
Пожаловаться на меня как модератора можно здесь.
PM MAIL Jabber   Вверх
MAKCim
Дата 20.1.2008, 23:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


Профиль
Группа: Экс. модератор
Сообщений: 5644
Регистрация: 10.12.2005
Где: Менск, РБ

Репутация: 2
Всего: 207



Цитата(warmonger_ @  20.1.2008,  23:13 Найти цитируемый пост)
что бы этого точно небыло, нужно пользоваться пространством имен

пространства имен здесь не причем

Добавлено через 2 минуты и 53 секунды
Цитата(JackYF @  20.1.2008,  23:15 Найти цитируемый пост)
А, по-моему, это чисто логическое отделение функций/классов, и линковищку на пространства имён с глубокой высокой башни.
Поправьте меня, если я не прав.

 smile 
прав



--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
warmonger_
Дата 20.1.2008, 23:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 155
Регистрация: 7.7.2007
Где: г. Киев

Репутация: 1
Всего: 3



Извините, сказал не подумавши. smile 
--------------------
Make everything as simple as possible, but not simpler.Albert Einstein
PM MAIL   Вверх
archimed7592
Дата 21.1.2008, 04:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Архимед
****


Профиль
Группа: Завсегдатай
Сообщений: 2531
Регистрация: 12.6.2004
Где: Moscow

Репутация: 6
Всего: 93



Цитата(MAKCim @  20.1.2008,  22:22 Найти цитируемый пост)
как быть с callback-функциями?

А какая с ними проблема? smile

Цитата(MAKCim @  20.1.2008,  22:22 Найти цитируемый пост)
не забываем, что форматы файлов специфицированы и просто так добавить какую-то информацию туда нельзя  smile

Да ладно, если больно надо будет - добавят в формат что нужно. Или есть какая-то резкая необходимость использовать именно специфированный кем-то там(кем?) формат?


--------------------
If you have an apple and I have an apple and we exchange apples then you and I will still each have one apple. But if you have an idea and I have an idea and we exchange these ideas, then each of us will have two ideas.
© George Bernard Shaw
PM Jabber   Вверх
MAKCim
Дата 21.1.2008, 10:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


Профиль
Группа: Экс. модератор
Сообщений: 5644
Регистрация: 10.12.2005
Где: Менск, РБ

Репутация: 2
Всего: 207



Цитата(archimed7592 @  21.1.2008,  04:13 Найти цитируемый пост)
Или есть какая-то резкая необходимость использовать именно специфированный кем-то там(кем?) формат? 

PE специфицирован
ELF тоже

Цитата(archimed7592 @  21.1.2008,  04:13 Найти цитируемый пост)
А какая с ними проблема? 

как ты такое отследишь?
Код

/* main.c */

int main() {
    return ((int (*)(void))dlsym(dlopen(NULL, RTLD_NOW), "foo"))();
}

Код

/* foo.c */

int foo(void) {
    return 0;
}
  
smile

Добавлено через 3 минуты и 38 секунд
так что с примером?  smile 
его фишка в том, что если компоновщик будет отслеживать зависимости, то в выходной файл не будет включена функция routine, что приведет к непредсказуемым последствиям


Это сообщение отредактировал(а) MAKCim - 21.1.2008, 10:28


--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
archimed7592
Дата 21.1.2008, 15:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Архимед
****


Профиль
Группа: Завсегдатай
Сообщений: 2531
Регистрация: 12.6.2004
Где: Moscow

Репутация: 6
Всего: 93



Цитата(MAKCim @  21.1.2008,  10:28 Найти цитируемый пост)
PE специфицирован
ELF тоже

А компилятор разве генерирует PE или ELF? smile
Я же говорил о том, что компилятор будет вкладывать информацию в объектники smile.


Цитата(MAKCim @  21.1.2008,  10:28 Найти цитируемый пост)
как ты такое отследишь?

Очень просто: если линкуется с флагом -rdynamic, то включать все глобальные ф-ции с внешним связываением вне зависимости от того, используются они или нет smile. Ежу понятно, что из dll/so ничего выкидывать не нужно, ибо использоваться оно будет внешними программами.


Цитата(MAKCim @  21.1.2008,  10:28 Найти цитируемый пост)
так что с примером?

А ничего... Я тебе говорю о С++(С), а не об ассемблере. В случае с ассемблером - просто включать весь модуль полностью, ибо реверсить асм вредно для здоровья smile.


--------------------
If you have an apple and I have an apple and we exchange apples then you and I will still each have one apple. But if you have an idea and I have an idea and we exchange these ideas, then each of us will have two ideas.
© George Bernard Shaw
PM Jabber   Вверх
MAKCim
Дата 21.1.2008, 17:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


Профиль
Группа: Экс. модератор
Сообщений: 5644
Регистрация: 10.12.2005
Где: Менск, РБ

Репутация: 2
Всего: 207



Цитата(archimed7592 @  21.1.2008,  15:42 Найти цитируемый пост)
А компилятор разве генерирует PE или ELF? smile
Я же говорил о том, что компилятор будет вкладывать информацию в объектники

объектные файлы являются форматными PE или ELF файлами
ELF формат, к примеру, специфицирует объектные, перемещаемые, исполняемые файлы, а также файлы динамических библиотек
с PE то же самое
Цитата(archimed7592 @  21.1.2008,  15:42 Найти цитируемый пост)
Ежу понятно, что из dll/so ничего выкидывать не нужно, ибо использоваться оно будет внешними программами.

DLL и SO тут вообще не причем
я просто привел один из способов вызова функции foo(), которая определена в отдельном модуле
причем компоновщик в этом случае просто не в состоянии определить, что foo на самом деле используется

Цитата(archimed7592 @  21.1.2008,  15:42 Найти цитируемый пост)
А ничего... Я тебе говорю о С++(С), а не об ассемблере. В случае с ассемблером - просто включать весь модуль полностью, ибо реверсить асм вредно для здоровья

ты наверное немного не в теме  smile 
компоновщик работает только с объектными файлами
а по ним невозможно определить, как они были получены: компиляцией кода на ЯВУ или трансляцией ассемблерного кода
вот есть две эквивалентные программы
Код

int main() { 
    return 0; 
}

и
Код

.text
main:
    xorl    %eax, %eax
    ret
.globl main

на выходе мы получим 2 объектных файла и невозможно будет определить, что один из них получен из исходника на ассемблере


--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
archimed7592
Дата 21.1.2008, 17:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Архимед
****


Профиль
Группа: Завсегдатай
Сообщений: 2531
Регистрация: 12.6.2004
Где: Moscow

Репутация: 6
Всего: 93



Цитата(MAKCim @  21.1.2008,  17:28 Найти цитируемый пост)
объектные файлы являются форматными PE или ELF файлами

Понятно, и тем не менее: объектники не используются дальше, чем до передачи их линкеру, т.е. можно немного усовершенствовать формат от чего никто не пострадает, разве нет?


Цитата(MAKCim @  21.1.2008,  17:28 Найти цитируемый пост)
я просто привел один из способов вызова функции foo(), которая определена в отдельном модуле

Отлично, но чтобы упомянутый тобою способ работал нужно собрать исполняемый файл в таком режиме, когда все сущности с внешним связыванием засовываются в специальную таблицу экспорта, т.е. в дальнейшем исполняемый файл можно использовать как dll/so т.е. принципиальной разницы нет, так?


Цитата(MAKCim @  21.1.2008,  17:28 Найти цитируемый пост)
ты наверное немного не в теме  smile 
компоновщик работает только с объектными файлами

Возможно я и не в теме smile, но компилятор точно знает с чем он работает(асм или С/C++) и если он в состоянии(т.е., если он работает с C/C++), то ничто не мешает ему добавить эту информацию в объектник. Если же этой информации нет(т.е. компилятор был не в состоянии её добавить), то линкер вправе работать "по старинке".


--------------------
If you have an apple and I have an apple and we exchange apples then you and I will still each have one apple. But if you have an idea and I have an idea and we exchange these ideas, then each of us will have two ideas.
© George Bernard Shaw
PM Jabber   Вверх
MAKCim
Дата 21.1.2008, 18:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


Профиль
Группа: Экс. модератор
Сообщений: 5644
Регистрация: 10.12.2005
Где: Менск, РБ

Репутация: 2
Всего: 207



Цитата(archimed7592 @  21.1.2008,  17:42 Найти цитируемый пост)
т.е. можно немного усовершенствовать формат от чего никто не пострадает, разве нет?

хорошо, какие конкретно дополнительные данные ты предлагаешь помещать в объектный файл?
Цитата(archimed7592 @  21.1.2008,  17:42 Найти цитируемый пост)
Отлично, но чтобы упомянутый тобою способ работал нужно собрать исполняемый файл в таком режиме, когда все сущности с внешним связыванием засовываются в специальную таблицу экспорта, т.е. в дальнейшем исполняемый файл можно использовать как dll/so т.е. принципиальной разницы нет, так?

не понял
здесь обычный исполняемый файл, который собирается из 2-х модулей
в первом определена main(), во-втором - foo()
также есть ссылка на dlopen()/dlsym() из libdl.so
если компоновщик будет пытаться избавиться от ненужного "мусора", то в этот "мусор" попадет и foo(), которая на самом деле используется, но на которую нет прямой ссылки из объектного файла, где определена main()
Цитата(archimed7592 @  21.1.2008,  17:42 Найти цитируемый пост)
Если же этой информации нет(т.е. компилятор был не в состоянии её добавить), то линкер вправе работать "по старинке". 

ответь на первый вопрос


--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
archimed7592
Дата 21.1.2008, 18:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Архимед
****


Профиль
Группа: Завсегдатай
Сообщений: 2531
Регистрация: 12.6.2004
Где: Moscow

Репутация: 6
Всего: 93



Цитата(MAKCim @  21.1.2008,  18:18 Найти цитируемый пост)
хорошо, какие конкретно дополнительные данные ты предлагаешь помещать в объектный файл?

Для каждой ф-ции: список сущностей от которых зависит данная ф-ция(как внутримодульных, так и внешних). Причём, если "нужная" ф-ция заинлайнена, то от неё мы не зависим.

Цитата(MAKCim @  21.1.2008,  18:18 Найти цитируемый пост)
не понял
здесь обычный исполняемый файл, который собирается из 2-х модулей

Не совсем обычный - он компонуется с ключем -rdynamic, а иначе он работать не будет, даже если foo не будет выкинута компоновщиком... разве нет?


--------------------
If you have an apple and I have an apple and we exchange apples then you and I will still each have one apple. But if you have an idea and I have an idea and we exchange these ideas, then each of us will have two ideas.
© George Bernard Shaw
PM Jabber   Вверх
xvr
Дата 21.1.2008, 18:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 35
Всего: 223



Вообще то и gcc (точнее ld) и BCB давно умеют линковать только нужные функции в исполняемый файл. Достигается это очень просто - каждая функция помещается компилятором в свой собственный сегмент кода (отдельный от всех других). Линкер на этапе сборки выкидывает сегменты, к меткам, описанным в которых, нет ссылок.
Кстати, этот процесс во многом аналогичен линковке со статическими библиотеками, что есть вообще везде с самого начала.
PM MAIL   Вверх
MAKCim
Дата 21.1.2008, 21:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


Профиль
Группа: Экс. модератор
Сообщений: 5644
Регистрация: 10.12.2005
Где: Менск, РБ

Репутация: 2
Всего: 207



xvr, 
гы
ты бы лучше сначала проверил, чем сразу утверждать  smile

Добавлено через 1 минуту и 38 секунд
Цитата(archimed7592 @  21.1.2008,  18:27 Найти цитируемый пост)
Не совсем обычный - он компонуется с ключем -rdynamic, а иначе он работать не будет, даже если foo не будет выкинута компоновщиком... разве нет?

да, все верно
но файл все равно останется исполняемым, только с расширенной таблицей .dynsym



--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
archimed7592
Дата 21.1.2008, 22:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Архимед
****


Профиль
Группа: Завсегдатай
Сообщений: 2531
Регистрация: 12.6.2004
Где: Moscow

Репутация: 6
Всего: 93



Цитата(MAKCim @  21.1.2008,  21:48 Найти цитируемый пост)
но файл все равно останется исполняемым, только с расширенной таблицей .dynsym

Ну так вот, я на это ответил раньше(на изначально поставленный вопрос):
Цитата(archimed7592 @  21.1.2008,  15:42 Найти цитируемый пост)
Очень просто: если линкуется с флагом -rdynamic, то включать все глобальные ф-ции с внешним связываением вне зависимости от того, используются они или нет

Т.е., при компоновке с этим ключиком сущности с внешним связыванием не рассматриваются как кандидаты на исключение из итогового бинарника, ибо есть вероятность(раз этот ключик указан), что исполняемый файл будет использоваться как библиотека с динамическим связыванием.


--------------------
If you have an apple and I have an apple and we exchange apples then you and I will still each have one apple. But if you have an idea and I have an idea and we exchange these ideas, then each of us will have two ideas.
© George Bernard Shaw
PM Jabber   Вверх
MAKCim
Дата 21.1.2008, 22:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


Профиль
Группа: Экс. модератор
Сообщений: 5644
Регистрация: 10.12.2005
Где: Менск, РБ

Репутация: 2
Всего: 207



Цитата(archimed7592 @  21.1.2008,  22:12 Найти цитируемый пост)
не рассматриваются как кандидаты на исключение из итогового бинарника

ничего не исключается 
идет лишь добавление символов в .dynsym, а она в свою очередь используется при поиске символов

Добавлено через 1 минуту и 31 секунду
вообщем, если подытожить, задача исключения сложна, но решаема
я в принципе обратного и не утверждал


--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
archimed7592
Дата 21.1.2008, 22:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Архимед
****


Профиль
Группа: Завсегдатай
Сообщений: 2531
Регистрация: 12.6.2004
Где: Moscow

Репутация: 6
Всего: 93



Так, Макс, блин, кому-то из нас двоих однозначно пора спать smile.

Ты спросил:
Цитата(MAKCim @  21.1.2008,  10:28 Найти цитируемый пост)
Цитата(archimed7592 @  21.1.2008,  04:13 Найти цитируемый пост)
А какая с ними проблема? 

как ты такое отследишь?
Код

/* main.c */

int main() {
    return ((int (*)(void))dlsym(dlopen(NULL, RTLD_NOW), "foo"))();
}

Код

/* foo.c */

int foo(void) {
    return 0;
}
  
smile
Я тебе ответил: отслежу по ключику -rdynamic. Если он есть, то добавляем все ф-ции вне зависимости от их реальной используемости(точно так же, как если бы мы собирали .so).


Теперь ты мне говоришь:
Цитата(MAKCim @  21.1.2008,  22:24 Найти цитируемый пост)
ничего не исключается 
С моей стороны вопрос: а где я сказал, что что-то исключается? smile

---------------------------------------------------------
Я, на всякий случай напомню предмет нашей беседы: тривиальна или нетривиальна задача исключения ненужного кода. Т.е. разговариваем мы с тобой о неком вымышленном тулчайне, в котором такая возможность будет и пытаемся понять возможен ли такой тулчайн в реальности, таким образом, даже если я говорю "что-то там куда-то там исключается", я имею в виду мой вымышленный компоновщик. Угу?

Добавлено через 49 секунд
Или не угу? smile

Добавлено через 5 минут и 4 секунды
Цитата(MAKCim @  21.1.2008,  22:24 Найти цитируемый пост)
вообщем, если подытожить, задача исключения сложна, но решаема
я в принципе обратного и не утверждал 

Вот даже как smile. Хорошо ты подытожил, красиво smile.
Давай я тоже подытожу: я не увидел ни NP-полноты задачи, ни необозримого множества ньансов, которые нужно предусмотреть, так что задача классическая: есть три ф-ции(A, B, C), причём A зависит от B, а B зависит от C, значит A зависит от B и С smile.


--------------------
If you have an apple and I have an apple and we exchange apples then you and I will still each have one apple. But if you have an idea and I have an idea and we exchange these ideas, then each of us will have two ideas.
© George Bernard Shaw
PM Jabber   Вверх
MAKCim
Дата 21.1.2008, 22:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


Профиль
Группа: Экс. модератор
Сообщений: 5644
Регистрация: 10.12.2005
Где: Менск, РБ

Репутация: 2
Всего: 207



Цитата(archimed7592 @  21.1.2008,  22:35 Найти цитируемый пост)
Так, Макс, блин, кому-то из нас двоих однозначно пора спать 

рано  smile 
Цитата(archimed7592 @  21.1.2008,  22:35 Найти цитируемый пост)
Я тебе ответил: отслежу по ключику -rdynamic. Если он есть, то добавляем все ф-ции вне зависимости от их реальной используемости(точно так же, как если бы мы собирали .so).

да
Цитата(archimed7592 @  21.1.2008,  22:35 Найти цитируемый пост)
С моей стороны вопрос: а где я сказал, что что-то исключается?

Цитата(archimed7592 @  21.1.2008,  22:12 Найти цитируемый пост)
не рассматриваются как кандидаты на исключение из итогового бинарника

под исключением я подразумевал, что в текущей реализации компоновщика LD ничего не исключается, а секции выходного файла формируются из целых секций входных файлов
Цитата(archimed7592 @  21.1.2008,  22:35 Найти цитируемый пост)
я имею в виду мой вымышленный компоновщик. Угу?

вот
с этого и надо было начинать
тогда все стало на свои места  smile 
Цитата(archimed7592 @  21.1.2008,  22:35 Найти цитируемый пост)
Давай я тоже подытожу: я не увидел ни NP-полноты задачи, ни необозримого множества ньансов, которые нужно предусмотреть, так что задача классическая: есть три ф-ции(A, B, C), причём A зависит от B, а B зависит от C, значит A зависит от B и С

это теория
она абстрагирует от деталей, в которых обычно и кроются сложности
если все так просто, почему этого до сих пор нет в LD или других компоновщиках (хотя про другие не могу дать 100%-ой гарантии)


--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
archimed7592
Дата 21.1.2008, 23:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Архимед
****


Профиль
Группа: Завсегдатай
Сообщений: 2531
Регистрация: 12.6.2004
Где: Moscow

Репутация: 6
Всего: 93



Цитата(MAKCim @  21.1.2008,  22:50 Найти цитируемый пост)
рано  smile 

А я, с Вашего позволения, пойду подремлю smile.

Цитата(MAKCim @  21.1.2008,  22:50 Найти цитируемый пост)
если все так просто, почему этого до сих пор нет в LD или других компоновщиках

Конкретно про LD - думаю причина в том, что, либо используемый формат объектников дорабатывать будет дорогого стоить, а переходить на новый формат родит проблемы с совместимостью. Но тем не менее я не вижу ни одной серьёзной проблемы, чтобы воплотить в жизнь эту фичу.


--------------------
If you have an apple and I have an apple and we exchange apples then you and I will still each have one apple. But if you have an idea and I have an idea and we exchange these ideas, then each of us will have two ideas.
© George Bernard Shaw
PM Jabber   Вверх
xvr
Дата 22.1.2008, 00:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 35
Всего: 223



Цитата(MAKCim @ 21.1.2008,  21:48)
xvr, 
гы
ты бы лучше сначала проверил, чем сразу утверждать  smile

Обычно я утверждаю то, что знаю  smile 
BCB 6.0
u2.cpp
Код

//---------------------------------------------------------------------------

#pragma hdrstop

#include "U2.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)

int func1() {return 1;}
int func0() {return 0;}

U1.cpp
Код

//---------------------------------------------------------------------------

#pragma hdrstop

#include "u2.h"

//---------------------------------------------------------------------------

#pragma argsused
int main(int argc, char* argv[])
{
        return func0();
}
//---------------------------------------------------------------------------

Ассемблер (выдержка) для U2.cpp:
Код

_TEXT    segment dword public use32 'CODE'
@func1$qv    segment virtual
@@func1$qv    proc    near
?live16385@0:
 ;    
 ;    int func1() {return 1;}
 ;    
    push ebp
    mov ebp,esp
@1:
    mov eax,1
@3:
@2:
    pop ebp
    ret 
@@func1$qv    endp
@func1$qv    ends
_TEXT    ends
_TEXT    segment dword public use32 'CODE'
@func0$qv    segment virtual
@@func0$qv    proc    near
?live16386@0:
 ;    
 ;    int func0() {return 0;}
 ;    
    push ebp
    mov ebp,esp
@4:
    xor eax,eax
@6:
@5:
    pop ebp
    ret 
@@func0$qv    endp
@func0$qv    ends
_TEXT    ends

Обратите внимание на директиву @func0$qv    segment virtual
Результат - функции func1 в выходном exe'нике нет, желающие могут убедится лично (см атач)

Что касается gcc - то он тоже делает отдельные сегменты и выкидывает ненужные, но только если его попросить:
g++ -fdata-sections -ffunction-sections -Wl,--gc-sections
qq.cc
Код

int func0() {return 0;}
int func1() {return 1;}

qq.s
Код

    .file    "qq.cc"
    .section    .text$_Z5func0v,"x"
    .align 2
.globl __Z5func0v
    .def    __Z5func0v;    .scl    2;    .type    32;    .endef
__Z5func0v:
    pushl    %ebp
    movl    %esp, %ebp
    movl    $0, %eax
    popl    %ebp
    ret
    .section    .text$_Z5func1v,"x"
    .align 2
.globl __Z5func1v
    .def    __Z5func1v;    .scl    2;    .type    32;    .endef
__Z5func1v:
    pushl    %ebp
    movl    %esp, %ebp
    movl    $1, %eax
    popl    %ebp
    ret

К сожалению мне не удалось заставить ld под cygwin'ом обработать --gc-sections, вероятно слишком древняя версия gcc (3.4.4), если будет желание - могу попробовать на работе, там вроде есть 4.х


Присоединённый файл ( Кол-во скачиваний: 2 )
Присоединённый файл  p2.rar 5,65 Kb
PM MAIL   Вверх
MAKCim
Дата 22.1.2008, 10:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


Профиль
Группа: Экс. модератор
Сообщений: 5644
Регистрация: 10.12.2005
Где: Менск, РБ

Репутация: 2
Всего: 207



xvr, 
да, с LD я оказался не прав
признаю свою ошибку
не сопоставил --gc-sections LD с -ffunction-sections GCC
вместе они дают нужный результат
держи заслуженный плюс, а я  smile

Добавлено через 2 минуты и 51 секунду
archimed7592, 
тебе тоже плюс за остаивание позиции  smile 


--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
Страницы: (3) [Все] 1 2 3 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Для новичков"
JackYF
bsa

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, bsa.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Для новичков | Следующая тема »


 




[ Время генерации скрипта: 0.0962 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.