[gcc] размер пустого объекта

Landstreicher

Объясните пожалуйста результат работы такой программы:


#include <stdio.h>
class A
{
public:
inline ~A {}
};
inline unsigned long stack
{
char c;
return (unsigned long)&c;
}
#define MAX 10
unsigned long addr[MAX];
void test1
{
static int depth = 0;
if (depth >= MAX) return;

addr[depth] = stack;
depth++; test1; depth--;
}
void test2
{
static int depth = 0;
if (depth >= MAX) return;

A a;
addr[depth] = stack;
depth++; test2; depth--;
}
int main
{
int i;
printf("Test 1 (no object)\n");
test1;
for (i = 0; i < (MAX - 2); i++) {
printf("%d\n", addr[i] - addr[i+1]);
}
printf("Test 1 (with object)\n");
test2;
for (i = 0; i < (MAX - 2); i++) {
printf("%d\n", addr[i] - addr[i+1]);
}
}


У меня наблюдается такая картина:


[lorien ~]$ g++ -O3 -fomit-frame-pointer 3.cpp
3.cpp: In function `long unsigned int stack':
3.cpp:11: warning: address of local variable `c' returned
[lorien ~]$ ./a.out
Test 1 (no object)
24
8
8
8
8
8
8
8
Test 1 (with object)
64
64
64
64
64
64
64
64
[lorien ~]$


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

GalinaG

Компилятор 3.4.0 руками собранный
aliki:~$ ./a.out
Test 1 (no object)
16
16
16
16
16
16
16
16
Test 1 (with object)
48
48
48
48
48
48
48
48

tokuchu

Может быть align какой-нибудь?

Landstreicher

процессор у меня 32-битный, поэтому align должен быть 4 или 8. Следовательно, логично ожидать лишних 4-8 байт. Но 56 откуда?

Landstreicher

безусловно, 32 это лучше чем 56. Но все равно тратить 32 байта на абсолютно пустой объект... Нет, я этого не понимаю.

Ivan8209

Выравнивание на границу страницы памяти?
---
...Я работаю антинаучным аферистом...

Chupa

гы


$ ./a.out
Test 1 (no object)
128
128
128
128
128
128
128
128
Test 1 (with object)
160
160
160
160
160
160
160
160


(не гцц, не линух, не иа32)

Landstreicher

поскольку рекурсия делается несколько раз, то тогда по идее каждый раз должно быть число в райное размера страницы. Страница в 56 байт? Не может быть такого...

Landstreicher

Какой компилятор?
Есть ли в ассемблерном листинге какие-нибудь попытки использовать это пустое место?

Ivan8209

Приплюснутую прогу не осилил.
Что говорит "gcc -S"?
В сях стек один, и на нём хранится всё, что только душа
компиляторописателя пожелает.
---
...Я работаю антинаучным аферистом...

Ivan8209



bash-2.05b# g++ alex.c
alex.c: In function `long unsigned int stack':
alex.c:11: warning: address of local variable `c' returned
bash-2.05b# ./a.out
Test 1 (no object)
16
16
16
16
16
16
16
16
Test 1 (with object)
48
48
48
48
48
48
48
48
bash-2.05b# g++ --version
g++ (GCC) 3.3.3 [FreeBSD] 20031106


---
...Я работаю антинаучным аферистом...

eee1


%g++ -O3 -fomit-frame-pointer lorien.cpp
%./a.out
Test 1 (no object)
48
32
32
32
32
32
32
32
Test 1 (with object)
63
48
48
48
48
48
48
48
%g++ -v
Using builtin specs.
gcc version 2.95.4 20020320 [FreeBSD]

%g++34 -O3 -fomit-frame-pointer lorien.cpp
lorien.cpp: In function `long unsigned int stack':
lorien.cpp:11: warning: address of local variable `c' returned
%./a.out
Test 1 (no object)
44
8
8
8
8
8
8
8
Test 1 (with object)
71
48
48
48
48
48
48
48
%g++34 -v
Reading specs from /usr/local/lib/gcc/i386-portbld-freebsd4.9/3.4.2/specs
Configured with: ./..//gcc-3.4-20040827/configure --disable-nls --with-system-zlib --with-libiconv-prefix=/usr/local --program-suffix=34 --with-gxx-include-dir=/usr/local/lib/gcc/i386-portbld-freebsd4.9/3.4.2/include/c++/ --disable-shared --prefix=/usr/local i386-portbld-freebsd4.9
Thread model: posix
gcc version 3.4.2 20040827 (prerelease) [FreeBSD]

Ivan8209

Я посмотрел на выдачу gcc -S.
Да, они никуда не тратятся.
Значит, это просто гнусь чего-то оптимизировала неполностью.
---
...Я работаю антинаучным аферистом...

Landstreicher

Есть подозрение, что тут что-то связано с C++ exceptions. Если отключить все оптимизации, то в коде появляются инструкции типа call _Unwind_Resume. То есть похоже это место резервируется под какие-то структуры, необходимые для обработки исключений. Если сказать -fno-exceptions, то этот вызова исчезает, но распределение памяти остается прежнее. Если делать оптимизации, то весь мусор уходит, в результате это место вообще не используется.
Похоже ли это на правду? Какие есть идеи?
Где взять доку по тому как внутри устроена обработка исключений в GNU C++?

Chupa

я не понял, что ты называешь "пустым местом"
компилер: IBM VisualAge
прикол: если код скомпилить гцц 3.3 с "-fno-exceptions -O0", то он юзает 48 байт на вызов
а при замене "A a;" на "A a[0];" или на "A a[1];" -- уже 64
прикол2: попробуй -Os

shlyumper

Test 1 (no object)
120
120
120
120
120
120
120
120
Test 1 (with object)
120
120
120
120
120
120
120
120

[sundev010] ~ > gcc -v
Reading specs from /usr/local/lib/gcc-lib/sparc-sun-solaris2.8/egcs-2.91.66/specs
gcc version egcs-2.91.66 19990314/Linux (egcs-1.1.2 release)

garikus



aix% g++ -v
Using built-in specs.
Configured with: FreeBSD/i386 system compiler
Thread model: posix
gcc version 3.4.2 [FreeBSD] 20040728
aix% g++ -Os -fomit-frame-pointer ic_test.cpp
ic_test.cpp: In function `long unsigned int stack':
ic_test.cpp:11: warning: address of local variable `c' returned
aix% ./a.out
Test 1 (no object)
8
8
8
8
8
8
8
8
Test 1 (with object)
24
24
24
24
24
24
24
24


Интересно, какой результат будет, если использовать компилятор Intel? Он же есть под Linux, кто-нибудь может попробовать? У меня он CPP не компилирует (проблемы в FreeBSD).

Chupa

гыгы (icc 8.0, без каких-либо дополнительных ключей)
Test 1 (no object)
8
8
8
8
8
8
8
8
Test 1 (with object)
8
8
8
8
8
8
8
8

Landstreicher

О! Очень интересный результат.
Этот компилятор прорюхал все или же он просто про exceptions не знает?
Кстати, почему 120 байт? Как-то много? -O3 указывал?

Chupa

> почему 120 байт?
sparc

Landstreicher

Мегареспект интелу! Пошел скачивать icc
Все-таки хотелось бы найти у gcc какой-нибудь ключ типа -fno-kakaya-nibud-hren чтобы вызывать похоже поведение.

Landstreicher

-Os это вообще прикол.
Я правильно понимаю, что все -O.. просто включают/выключают множество опций типа -fчто-то -fno-что-то? Если да, то можно попытаться скомбинировать ключи из -O2 и -Os.

Chupa



-Os Optimize for size. -Os enables all -O2 optimizations that do not typ-
ically increase code size. It also performs further optimizations
designed to reduce code size.
-Os disables the following optimization flags: -falign-functions
-falign-jumps -falign-loops -falign-labels -freorder-blocks
-fprefetch-loop-arrays
If you use multiple -O options, with or without level numbers, the
last such option is the one that is effective.

Оставить комментарий
Имя или ник:
Комментарий: