Как компоновщик создает исполняемые файлы и связывает ключевые слова C.

#c #gcc #compiler-construction #linker #elf

#c #gcc #компилятор-построение #компоновщик #elf

Вопрос:

Я создал 2 программы на C в Ubuntu (Linux 2.6), как показано ниже

 1.c
----
main()
{
}

2.c
----
#include<stdio.h>
main()
{
int a[500];
float f[1000];
double d[100000];
int i = 0;
for(i = 0;i < 10000;i  );  // Intentional ;
for(i = 0;i < 10000;i  );  // Intentional ;
for(i = 0;i < 10000;i  );  // Intentional ;
for(i = 0;i < 10000;i  );  // Intentional ;
if(1)
{
}
else
{
}
switch(1)
{
}
while(1);
}
  

После раздельной компиляции и создания исполняемых файлов я проверил размер обоих исполняемых файлов.К моему удивлению, размер обоих исполняемых файлов был одинаковым (7099 байт).

Однако размер объектного файла отличается.

Кто-нибудь, пожалуйста, объясните мне, почему размер исполняемого файла был одинаковым для program 1.c и 2.c.Программа 2.c должна была использовать больше места, а размер исполняемого файла должен был увеличиться, верно? Как компоновщик связывает ключевые слова C (например, int, float,while, if ..) и создает исполняемый файл?

Большое спасибо

Комментарии:

1. Попробуйте скомпилировать с -O0 помощью gcc. Я подозреваю, что ваши пустые операторы и неиспользуемые переменные оптимизируются из исполняемого файла. Просто мысль.

2. Какие параметры оптимизатора вы использовали? Переменные массива не используются и будут удалены; циклы ничего не дают, поэтому они не используются. while (1) Насколько я понимаю, цикл также может быть оптимизирован. Будьте осторожны с тем, что может сделать хороший оптимизатор!

3. Компоновщик не имеет никакого отношения ни к этому вопросу, ни к ключевым словам C.

4. @Jonathan Я только что использовал gcc 1.c

5. Какая версия GCC? 4.1.2 и 4.9.0 могут иметь разные результаты. Оптимизация будет иметь решающее значение.

Ответ №1:

Я считаю, что это связано с оптимизатором. Но для компоновщика я предлагаю прочитать пункты ниже, поскольку вы проявили любопытство к компоновщикам. Чтение этого поможет любому программисту на C amp; C . Знание того, что на самом деле означает связывание, является важным знанием.

Для получения дополнительной информации:

Примечание: это может быть не то, что вы искали, но самостоятельное изучение и изучение того, что вы ищете, продлит то, что вы узнали.

Комментарии:

1. @Vijay Если мой ответ разрешил ваш вопрос, пожалуйста, примите его, чтобы вопрос можно было закрыть.

Ответ №2:

Способен найти убедительное решение для заданного вопроса. Ниже приведен анализ и замечания по этому поводу.

В коде 2.c я добавил много операторов типа «for(i = 0;i < 10000;i ); // Преднамеренный ;». В какой-то момент заметил, что размер исполняемого файла 2.c увеличился на 4096 байт. Похоже, компоновщик по умолчанию выделяет 4k памяти для раздела кода, как указано в скрипте компоновщика для выравнивания СТРАНИЦ. Для x86 этот размер равен 4k (COMMONPAGESIZE). Только после того, как размер кода превышает более 4k, для раздела кода выделяется новый 4k памяти. Вот почему, когда было добавлено больше инструкций «for(i = 0; i < 10000; i ); // Intentional ;», размер исполняемого файла увеличился.