spamsink: (Default)
[personal profile] spamsink

Дано:
#include <stdio.h>
#include <stddef.h>

ptrdiff_t frame(char * prev) {
	char dummy;
	if (prev) {
		return prev - &dummy;
	}
	else return frame(&dummy);
}

void main() {
	printf("%ld\n", frame(0));
}

Что эта программа печатает, будучи скомпилирована с отключенной оптимизацией? Что - с включенной оптимизацией? Почему?

Date: 2014-10-25 08:20 pm (UTC)
From: [identity profile] proxfessor.livejournal.com
Вроде бы должна размер фрейма печатать. А про оптимизацию - вопрос некорректный: разные компиляторы по-разному оптимизируют.

Date: 2014-10-26 01:33 am (UTC)
From: [identity profile] proxfessor.livejournal.com
Компилятор gcc 4.6.3 для 64-битного Линукса. С опцией -O0 - 48; с -O1 - 32; с -O2 - 0; с -O3 - -1. Истолкуй!

Date: 2014-10-25 08:45 pm (UTC)
From: [identity profile] avva.livejournal.com
Моя догадка: без оптимизации размер фрейма. С оптимизацией оба вызова frame() будут inlined, и программа напечатает плюс или минус 2 или 4 или 8 в зависимости от архитектуры и направления роста стека.

Date: 2014-10-25 08:52 pm (UTC)
From: [identity profile] archaicos.livejournal.com
Что угодно, т.к. инстанции локальной переменной dummy не принадлежат одному массиву, а значит вычитание адресов инстанций друг из друга даёт undefined behavior.

Date: 2014-10-25 09:09 pm (UTC)
From: [identity profile] archaicos.livejournal.com
Какого нуля?

Кстати, %ld не соответствует ptrdiff_t — ещё одно UB.

Date: 2014-10-25 11:05 pm (UTC)
vak: (Default)
From: [personal profile] vak
А еще main() не бывает void. :)

Date: 2014-10-25 11:15 pm (UTC)
From: [identity profile] archaicos.livejournal.com
Оно в некотором роде на усмотрение реализации. Т.е. может поддерживаться, а может и нет.

Date: 2014-10-26 01:34 am (UTC)
vak: (Default)
From: [personal profile] vak
Ни gcc, ни clang не признают void main().

Date: 2014-10-26 01:37 am (UTC)
From: [identity profile] archaicos.livejournal.com
Имеют право.

Date: 2014-10-26 08:29 am (UTC)
From: [identity profile] archaicos.livejournal.com
Может быть что угодно подразумевает и ноль. :)

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

printf("%ld\n", (long)frame(0));

или для параноиков:

printf("%lld\n", (long long)frame(0));

Но есть один богомерзкий компилятор, который не понимает даже %lld и long long. :)

Date: 2014-10-25 10:52 pm (UTC)
ext_659502: (Default)
From: [identity profile] some41.livejournal.com
Ноль тоже может быть, потому что от переменной используется только адрес (по которому нет никаких записей), так что место на нее выделять не обязательно.

дополнение

Date: 2014-10-25 11:24 pm (UTC)
From: [identity profile] archaicos.livejournal.com
Но сам адрес переменной не может быть равен нулю.

Re: дополнение

Date: 2014-10-25 11:26 pm (UTC)
ext_659502: (Default)
From: [identity profile] some41.livejournal.com
Но разность двух может.

Re: дополнение

Date: 2014-10-25 11:33 pm (UTC)
From: [identity profile] archaicos.livejournal.com
Только в случае UB (тот самый случай в представленном нам коде) или если они лежат внутри union'а.

Re: дополнение

Date: 2014-10-25 11:45 pm (UTC)
ext_659502: (Default)
From: [identity profile] some41.livejournal.com
> тот самый случай в представленном нам коде
Так о чем спор?

Re: дополнение

Date: 2014-10-25 11:47 pm (UTC)
From: [identity profile] archaicos.livejournal.com
Спора нет. Просто уточняю.

Re: дополнение

Date: 2014-10-26 08:37 am (UTC)
From: [identity profile] archaicos.livejournal.com
Это издевательство явно прописано в стандарте языка. И мы вроде его уже обсуждали:
http://archaicos.livejournal.com/218516.html
Или у тебя остались вопросы или образовалась лёгкая потеря памяти?

Re: дополнение

Date: 2014-10-27 08:03 am (UTC)
From: [identity profile] archaicos.livejournal.com
Ну, допускается сравнение на (не)равенство. Что я там забыл?

C(++) делали, не следуя этому принципу.

http://c2.com/cgi/wiki?PrincipleOfLeastAstonishment:

"C++ is astonishing in that Stroustrup wrote a book (TheDesignAndEvolutionOfCpp) full of examples where PrincipleOfLeastAstonishment is violated, yet after reading it they mysteriously make sense..."

:)

http://lucumr.pocoo.org/2011/7/9/python-and-pola/:

Same $h!t, pretty much. :)

Date: 2014-10-25 09:19 pm (UTC)
From: [identity profile] fatoff.livejournal.com
Пиши применительно к какому компилятору для какой платформы с каким опциями компиляции. И вообще, что за отсталые интересы, в век, когда Функионал бороздит просторы Большого Театра?! :=]

Date: 2014-10-25 09:35 pm (UTC)
From: [identity profile] archaicos.livejournal.com
Ну, хоть не фунгианал! :)

Date: 2014-10-25 10:13 pm (UTC)
From: [identity profile] fatoff.livejournal.com
Фунги кто? Грибы где?
Edited Date: 2014-10-25 10:14 pm (UTC)

Date: 2014-10-25 11:12 pm (UTC)
vak: (Default)
From: [personal profile] vak
-1 это круто.
Ох уж эти инлайновые функции.

Date: 2014-10-28 02:36 am (UTC)
From: [identity profile] yuri-yurkevich.livejournal.com
Вообще-то этот код отображает приём для организации stack underflow,
Такая хакерская штука, чтобы перехватить управление чьим-то компьютером.
Она как раз через стек, говорят, работает.

Date: 2014-10-28 05:48 am (UTC)
From: [identity profile] yuri-yurkevich.livejournal.com
Я уже привык, однако, к тому, что у меня пароли прямо из головы читают.

Мы в довольно замкнутом мире живём, так что приходится проверять даже то, о чём думает собственная голова.
Page generated Mar. 6th, 2026 08:08 am
Powered by Dreamwidth Studios