Рассмотрим следующий код C:
#include <stdio.h>
typedef struct {
int a;
} TestType;
int main(){
int an_int;
TestType test;
// printf("%d\n",test.a);
{
TestType test;
test.a = 777;
printf("offset: %lld\n", &test.a - &an_int); // maybe 2?
}
printf("%d\n", test.a); // should be garbage
printf("offset: %lld\n", &test.a - &an_int); // maybe 1?
}
Я объявляю TestType test
, затем запускаю область и объявляю еще один TestType test
, следящий за первым. Ожидаемый вывод оператора print в конце - это то, что было в стеке. Скомпилировав с gcc -o stack-allocate-weird stack-allocate-weird.c
и запустив, я получаю вывод:
offset: 1
777
offset: 1
Так что эти два места одинаковы. Кроме того, valgrind ./stack-allocate-weird
не сообщает об ошибках. Раскомментирование первого оператора print дает ожидаемый результат:
-771776240
offset: 2
-771776240
offset: 1
Если вместо struct TestType
я просто объявляю int
, код работает так, как ожидалось (последний оператор print печатает мусор).
Я поместил код на сервер, скомпилировал его и получил:
offset: -2
0
offset: -1
Что тоже хорошо выглядит (полагаю, стек идет в противоположном направлении?). С другой стороны, перенос бинарного файла, скомпилированного на моем компьютере, на сервер дал исходный неверный вывод:
offset: 1
777
offset: 1
Это известная ошибка с gcc?
gcc -v
на моем компьютере говорит (куча других вещей и):
gcc version 7.4.0 (Ubuntu 7.4.0-1ubuntu1~18.04)
На сервере написано:
gcc version 8.3.1 20190223 (Red Hat 8.3.1-2) (GCC)
Так, может быть, это было исправлено где-то посередине?