В частности, это возникло в дискуссии:
В отношении потребления памяти, есть ли вероятность, что использование
struct
из двухint
файлов займет больше памяти, чем просто дваint
?
Или в языковых терминах:
#include <iostream>
struct S { int a, b; };
int main() {
std::cout << (sizeof(S) > sizeof(int) * 2 ? "bigger" : "the same") << std::endl;
}
Существует ли какая-либо разумная 1 (не обязательно общепринятая или текущая) среда, в которой эта маленькая программа напечатает bigger
?
1
4 ответа
Было бы совершенно неправдоподобно, что система, которая может получить доступ к памяти только в 64-битных блоках, могла бы иметь возможность использовать 32-битный размер «int» для совместимости с другими программами, которые могли бы получить срабатывание uint32_t, что повышает его тип. , В такой системе структура с четным числом значений типа «int», скорее всего, не будет иметь дополнительного заполнения, но структура с нечетным числом значений может, вероятно, сделать это.
С практической точки зрения единственный способ, которым структура с двумя значениями int будет нуждаться в заполнении, - это если бы выравнивание структуры было более чем в в два раза грубее, чем выравнивание для int. Это, в свою очередь, потребовало бы, чтобы выравнивание структур было более грубым, чем 64 бита, или чтобы размер int был меньше 32 бит. Последняя ситуация не была бы необычной сама по себе, но объединение обоих таким способом, который сделал бы выравнивание структуры более чем в два раза более грубым, чем выравнивание int, показалось бы очень странным.
Теоретически заполнение используется, чтобы обеспечить эффективный способ доступа к области памяти. Если добавление заполнения к 2-х целочисленной переменной увеличит эффективность, чем да, у нее может быть заполнение. Но практически я не сталкивался ни с одной структурой с 2-мя целочисленными битами заполнения.
Я знаю, что это не то, что вы просили, это не в духе вашего вопроса (поскольку вы, вероятно, имеете в виду стандартные классы макетов), но строго отвечая только на эту часть:
В отношении потребления памяти, существует ли вероятность, что использование структуры из двух целых занимает больше памяти, чем просто две?
Ответ вроде ... да
struct S
{
int a;
int b;
virtual ~S() = default;
};
с педантичным примечанием, что C ++ не имеет структур, у него есть классы. struct
- это ключевое слово, которое вводит объявление / определение класса.
В вашем конкретном примере struct S { int a, b; };
я не вижу никаких разумных аргументов для заполнения. int
должен быть уже естественно выровнен, и если это так, int *
может и должен быть естественным представлением для указателей, и нет необходимости в том, чтобы S *
отличались. А вообще:
Несколько редких систем имеют указатели с разными представлениями, например, int *
представляется как целое число, представляющее адрес «слова», а char *
представляет собой комбинацию адреса слова и байтового смещения в этом слове (где байтовое смещение сохраняется в ненужных старших битах, в противном случае слова адрес). Разыменование char *
происходит в программном обеспечении, загружая слово, а затем маскируя и сдвигая, чтобы получить правильный байт.
В таких реализациях может иметь смысл обеспечить минимальное выравнивание всех типов структуры, даже если это не является обязательным для элементов структуры, просто для того, чтобы беспорядок смещения в байтах не был необходим для указателей на эту структуру. Это разумно, учитывая struct S { char a, b; };
, sizeof(S) > 2
. В частности, я бы ожидал sizeof(S) == sizeof(int)
.
Я никогда лично не работал с такими реализациями, поэтому я не знаю, действительно ли они производят такие дополнения. Но реализация, которая делает это, была бы разумной и, по крайней мере, очень близкой к существующей реальной реализации.
Похожие вопросы
Новые вопросы
c++
C ++ - это язык программирования общего назначения. Первоначально он был разработан как расширение C и имеет аналогичный синтаксис, но теперь это совершенно другой язык. Используйте этот тег для вопросов о коде (который должен быть) скомпилирован с помощью компилятора C ++. Используйте тег для конкретной версии для вопросов, связанных с конкретной версией стандарта [C ++ 11], [C ++ 14], [C ++ 17], [C ++ 20] или [C ++ 23] и т. Д. .