Заметил одну интересную вещь. Если написать программу
int x = 0;
то внешняя переменная x, как ей и полагается, находится в .bss секции, где инициализируется нулём. Тоже самое должно происходить и с программой
int x;
ведь внешние переменные без явной инициализации должны обнуляться. Но если собирать такую программу командой
gcc -c test.c
т.е. как объектный файл, то переменной x в секции .bss не будет. Но при этом в таблице символов она присутствует и более того, если программу слинковать, то она в той секции окажется. Возникает вопрос: "Почему?".
На самом деле во втором случае имеет место не совсем определение переменной 'x'. В стандарте такая штука зовётся "tentative definition" (предварительное определение). Поведение такой штуки задаётся следующим образом: если не было внешних определений для данного идентификатора, то его поведение полностью идентично тому, как если бы он инициализировлся нулём.
При наличии же внешних объявлений, конструкция
int x;
просто считается объявлением идентификатора, определённого в другой единице трансляции. После линковки x примет то значение, которым его определили. Например:// file.c
#include <stdio.h>
int x;
int main() { printf("%d\n", x); }
$ gcc file.c && ./a.out
0
Т.е. поведение полностью идентично
int x = 0;
но если сделать следующим образом:
// add.c
int x = 1;
// file.c
#include <stdio.h>
int x;
int main() { printf("%d\n", x); }
$ gcc file.c add.c && ./a.out
1
то поведение изменится. Т.к. определяется такое поведение во время связывания, то запихнуть 'x' в секцию .bss без онного просто нельзя. Этим и объясняется отсутствие 'x' в .bss, но присутствие в таблице символов.
Комментариев нет:
Отправить комментарий
Примечание. Отправлять комментарии могут только участники этого блога.