Я читал this great post about memory layout of C programs. В нем говорится, что инициализированные глобальные переменные по умолчанию находятся в BSS segment, и если вы явно предоставляете значение глобальной переменной, то оно будет находиться в data segment.Почему компиляторы C и C++ помещают явно инициализированные и инициализированные по умолчанию глобальные переменные в разных сегментах?
Я проверил следующие программы на C и C++, чтобы изучить это поведение.
#include <iostream>
// Both i and s are having static storage duration
int i; // i will be kept in the BSS segment, default initialized variable, default value=0
int s(5); // s will be kept in the data segment, explicitly initialized variable,
int main()
{
std::cout<<&i<<' '<<&s;
}
Выход:
0x488020 0x478004
Таким образом, с выходом она явно выглядит как переменная I & сек находится в совершенно разных сегментах. Но если я удаляю инициализатор (начальное значение 5 в этой программе) из переменной S, а затем запускаю программу, он дает мне следующий результат.
Выход:
0x488020 0x488024
Таким образом, с выхода он явно выглядит как переменные я и s находится в том же (в этом случае BSS) сегмента.
Такое поведение также же в С.
#include <stdio.h>
int i; // i will be kept in the BSS segment, default initialized variable, default value=0
int s=5; // s will be kept in the data segment, explicitly initialized variable,
int main(void)
{
printf("%p %p\n",(void*)&i,(void*)&s);
}
Выход:
004053D0 00403004
Итак, опять же, мы можем сказать, глядя на выходе (средства, рассматривающим адрес переменных), как переменная i и s находится в совершенно разных сегментах. Но опять же, если я удаляю инициализатор (начальное значение 5 в этой программе) из переменной S, а затем запускаю программу, он дает мне следующий результат.
Выход:
004053D0 004053D4
Таким образом, с выхода он явно выглядит как переменные я и s находится в том же (в этом случае BSS) сегмента.
Почему компиляторы C и C++ помещают явно инициализированные и инициализированные по умолчанию глобальные переменные в разных сегментах? Почему существует различие в том, где находится глобальная переменная между инициализированными и явно инициализированными переменными по умолчанию? Если я не ошибаюсь, стандарты C и C++ никогда не говорят о стеке, куче, сегменте данных, сегменте кода, сегменте BSS и обо всех таких вещах, которые специфичны для реализации. Итак, возможно ли, чтобы реализация C++ сохраняла явно инициализированные и инициализированные по умолчанию переменные в тех же сегментах, а не сохраняла их в разных сегментах?
[.bss] (https://en.wikipedia.org/wiki/.bss): «Обычно в объектном файле хранится только длина раздела bss, но нет данных. Операционные системы могут используйте метод, называемый zero-fill-on-demand, чтобы эффективно реализовать сегмент bss « –
Feel privileged ... Мне когда-то пришлось использовать компилятор, который ставил статические переменные в' .data', если бы они имели '= 0' initializer, и в '.bss', если у них не было инициализатора. А также пришлось использовать одну и ту же кодовую базу для другого (разбитого) компилятора, который не инициализировал нулевые статические переменные, у которых не было инициализатора. –
Общая викторина: что означает BSS? –