Zmienne lokalne i ich adresy, czemu nie rosną w dół?

Zmienne lokalne i ich adresy, czemu nie rosną w dół?
0

Mam taki kod:

Kopiuj
#include <iostream>

void fun()
{
    int x;
    int y;
    std::cout << std::hex << "0x" << reinterpret_cast<unsigned*>(&x) << std::endl;
    std::cout << std::hex << "0x" << reinterpret_cast<unsigned*>(&y) << std::endl;
}

int main()
{
    fun();

    return 0;
}

Output:
0x0x7ffec0fe3da0
0x0x7ffec0fe3da4

Zgodnie z teorią stos rośnie w dół czyli wirtualny adres funkcji main() jest najwyższy ze wszystkich adresów funkcji w user spejcie dla danego programu. I podobnie ze zmiennymi najpierw x leci na stos a potem y. Więc spodziewałbym się że adres x-a będzie większy od adresu y-a a tak nie jest. Ale przynajmniej dla funkcji się zgadza adres main jest wyższy niż adres fun.

6

standard nie gwarantuje w jakiej kolejności zmienne będą występować w pamięci i może sobie je umieszczać w dowolnej kolejności w ramach optymalizacji, to nie ma nic wspólnego ze stosem

co innego na przykład pola w strukturze czy parametry funkcji

0

OK kumam czyli jakbym miał x i y w strukturze i zmienną struct na stosie to wtedy x miałby większy adres niż y.

1

a masz dostęp do wygenerowanego kodu maszynowego czy jakiejś innej niskopoziomowej reprezentacji, żeby zobaczyć, do czego jest to kompilowane?

obscurity napisał(a):

standard nie gwarantuje

Swoją drogą ja się tak naciąłem w Rust. Łączyłem to z JS przez WebAssembly i część JSowa wyciągała ręcznie zmienne ze struktur Rust w pamięci WebAssembly. I wszystko działało, ale po uploadzie okazało się, że serwer CI/CD korzysta z nowszej wersji kompilatora Rust i pieczołowicie wyliczone przeze mnie adresy mi się rozjechały 🤡 i program przestał prawidłowo działać (musiałem zmienić znowu te wartości).

Tak to jest, jak się zbyt mocno wchodzi w szczegóły implementacji i korzysta z rzeczy, które nie sa gwarantowane standardem. Inna wersja kompilatora i mi się rozwaliło.

0

nie, ja tak tylko teoretycznie pytam bo do rozmów o prace się przygotowuję a że dawno nie byłem na rozmowie z 7 lat to sporo pozapominałem

2
systemdquestion napisał(a):

OK kumam czyli jakbym miał x i y w strukturze i zmienną struct na stosie to wtedy x miałby większy adres niż y.

no wręcz przeciwnie, standard zapewnia że zmienne w strukturze będą leżały w pamięci w takiej kolejności w jakiej zostały zadeklarowane więc adres y będzie większy niż adres x. Tutaj na stos jest odkładana cała struktura. Adres będzie mniejszy dla y niż dla x tylko jeśli będą to parametry - wtedy faktycznie będą odkładane na stos po kolei i adres będzie malejący.
Ale jakie to ma wszystko znaczenie i czemu się tym interesujesz? Serio na rozmowach o pracę w c++ zadają takie pytania? To jeszcze głupsze niż pytania z algorytmów.

0

np. zadają pytania co zrobić aby nie można było zadeklarować obiektu danej klasy na stosie tylko na stercie. To jak ktoś tego nie słyszał to ja wątpię aby wpadł na rozmowie że dam destruktor jako delete albo niepubliczny. Od znajomych co się rekrutowali słyszałem.

1

https://godbolt.org/z/19KozcbE3
GCC i Clang tutaj robią tak jakbyś się spodziewał. MSVC na odwrót - wie z góry ile zajmie ramka (bo nie ma żadnego VLA), więc sobie alokuje tak jak chce.

3
obscurity napisał(a):
systemdquestion napisał(a):

OK kumam czyli jakbym miał x i y w strukturze i zmienną struct na stosie to wtedy x miałby większy adres niż y.

no wręcz przeciwnie, standard zapewnia że zmienne w strukturze będą leżały w pamięci w takiej kolejności w jakiej zostały zadeklarowane więc adres x będzie większy niż adres y. Tutaj na stos jest odkładana cała struktura. Adres będzie mniejszy dla y niż dla x tylko jeśli będą to parametry - wtedy faktycznie będą odkładane na stos po kolei i adres będzie malejący.
Ale jakie to ma wszystko znaczenie i czemu się tym interesujesz? Serio na rozmowach o pracę w c++ zadają takie pytania? To jeszcze głupsze niż pytania z algorytmów.

Nay. Wręcz przeciwnie, adresy w strukturze/klasie rosną. https://godbolt.org/z/ve9hT3PrE A poza strukturą nie możesz sobie porównywać adresów niepowiązanych obiektów, i np. gcc robi z tego użytek jak widać.

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.