Ubuntu хранит переменные в неправильном порядке

Таким образом, у меня было это упражнение в моем классе, где я должен был сказать, какой из двух адресов больше, когда я создал два символа в основной функции.

Потому что локальные переменные хранятся в стеке, который начинается с высокого адреса и снижается до низкого адреса. Ответ был прост: первый символ имеет больший адрес.

Но потом я написал небольшую тестовую программу:

#include "stdio.h"

int main(void)
{
    int a = 3;
    int b = 4;

    printf("Size a: %lu \n"
           "size b: %lu \n",
           sizeof(a),
           sizeof(b));

    printf("Address a: %p \n"
           "Address b: %p \n",
           (void *)&a,
           (void *)&b);

    return 0;
}

Выход:

Size a: 4 
size b: 4 
Address a: 0x7fffa1eb8a98 
Address b: 0x7fffa1eb8a9c 

Вывод вводил в заблуждение, адрес второго символа был больше. Я попробовал то же самое на компьютере в моем университете, и все было хорошо. Вы знаете, почему это так?

Я на Ubuntu 13.04 64bit.

2 ответа

Решение

Стандарт C, как он определен Kernighan & Ritchie в их книге "Язык программирования C", не определяет, как параметры передаются в функции, не определяет, как хранятся локальные переменные, что определяет его реализацию.

В документации вашего компилятора должно быть указано, как передаются параметры, потому что в противном случае вы не сможете написать ассемблерный код для связи с ним. Для локальных переменных ограничений еще меньше, так как они будут доступны только из функции, поэтому компилятор может решить вообще не хранить переменную в памяти, если он может сохранить ее в регистре. Поскольку вы запрашивали адрес переменной, компилятор был вынужден сохранить его в памяти, но если вы не используете указатель на конкретную переменную, это не требуется.

Два разных компилятора могут делать разные вещи. Многие компиляторы предпочитают использовать стек, но другие вместо этого будут использовать регистры там, где это возможно, и даже там, где они используют стек, порядок параметров зависит от реализации.

Стандарт ANSI C как не изменил это.

Короче говоря, Ubuntu не хранит переменные в неправильном порядке. Компилятор, который вы используете в Ubuntu, просто сохраняет их в другом порядке, чем тот, который вы используете в университете. Ни один не так. Они просто разные, и документация компилятора должна объяснить, как это реализовано.

Для gcc, который большинство людей использует в Linux, документация здесь.

Я не думаю, что понимаю причину проблемы, но думаю, что GCC может иметь к этому какое-то отношение... Вот сравнение между GCC и Clang.

$ gcc -o test.gcc test.c
$ ./test.gcc
Size a: 4 
size b: 4 
Address a: 0x7fffeef71488 
Address b: 0x7fffeef7148c 


$ clang++ -o test.clang test.c 
$ ./test.clang 
Size a: 4 
size b: 4 
Address a: 0x7fff664573f8 
Address b: 0x7fff664573f4

Компилятор и его версия, которую вы используете в uni, могут быть здесь элементом переменной.

Другие вопросы по тегам