HLFX.Ru Forum
Показать все 19 сообщений этой темы на одной странице

HLFX.Ru Forum (https://hlfx.ru/forum/index.php)
- Технические вопросы (https://hlfx.ru/forum/forumdisplay.php?forumid=20)
-- Задачка на сообразительность (https://hlfx.ru/forum/showthread.php?threadid=4839)


Отправлено XaeroX 13-08-2016 в 15:44:

Хитрота Задачка на сообразительность

Задачка старая, и очень простая на первый взгляд.

1) Требуется написать корректный и переносимый код на языке С: функция foo, единственное предназначение которой - возврат указателя на саму себя. Иными словами, вот такой код должен компилироваться, работать и соответствовать стандарту:

C++ Source Code:
foo_t pf = foo(); // вызов foo
pf(); // вызов foo


2) То же, но на языке С++.

__________________

xaerox on Vivino


Отправлено ComradeAndrew 14-08-2016 в 05:55:

XaeroX
1)

C++ Source Code:
1
typedef void* (*foo_t)();
2
 
3
void* foo() {
4
  return foo;
5
}
6
 
7
int main()
8
{
9
  foo_t pf = foo(); // вызов foo
10
  pf(); // вызов foo
11
}


2) На c++ чем-то сильно отличается?


Отправлено XaeroX 14-08-2016 в 06:18:

ComradeAndrew
Это очевидный вариант, но он в общем случае неверный.
Кто тебе сказал, что sizeof(void*) равен sizeof(foo_t)?

Добавлено 14-08-2016 в 13:18:

Цитата:
ComradeAndrew писал:
На c++ чем-то сильно отличается?

Ну как минимум твой код в с++ не скомпилируется, потому что там нет приведения от void* по умолчанию.

__________________

xaerox on Vivino


Отправлено ComradeAndrew 14-08-2016 в 06:41:

Цитата:
XaeroX писал:
Ну как минимум твой код в с++ не скомпилируется, потому что там нет приведения от void* по умолчанию.

Это в стандарте так описано или ещё какие-то компиляторы так делают? У меня-то собирается.
Задача именно в том, чтобы все было по стандарту или работало на компиляторах всех платформ?
Цитата:
XaeroX писал:
sizeof(void*) равен sizeof(foo_t)

Может быть иначе? Не представляю при каких условиях.

Добавлено 14-08-2016 в 09:41:

Допустим такой код исправляет то о чем ты говоришь? Или я каких-то принципиальных моментов задачи не понимаю?
C++ Source Code:
foo_t foo() {
  return foo;
}


Отправлено XaeroX 14-08-2016 в 07:29:

Цитата:
ComradeAndrew писал:
Это в стандарте так описано или ещё какие-то компиляторы так делают? У меня-то собирается.

Why must I use a cast to convert from void*?
Цитата:
ComradeAndrew писал:
Может быть иначе? Не представляю при каких условиях.

Гм. Ну я тоже не представляю, при каких условиях int может быть не четырёхбайтовым, а в байте может быть не 8 битов. Но переносимый код должен учитывать, что стандарт описывает не всё, и кое-какие вещи остаются на усмотрение разработчика компилятора.
Цитата:
ComradeAndrew писал:
Допустим такой код исправляет то о чем ты говоришь?

Зависит от того, как ты определил foo_t.

__________________

xaerox on Vivino


Отправлено ComradeAndrew 14-08-2016 в 07:41:

Цитата:
XaeroX писал:
Why must I use a cast to convert from void*?

Там ведь показаны примеры кастов в разные типы. А тут-то: foo_t -> void* -> foo_t
Разве не безопасно?


Отправлено XaeroX 14-08-2016 в 08:17:

ComradeAndrew
Безопасно. Но компилятор об этом не знает. Foo может быть определена вообще в другой единице трансляции.

Добавлено 14-08-2016 в 15:17:

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

__________________

xaerox on Vivino


Отправлено Government-Man 14-08-2016 в 08:54:

Мух-ха-ха

Скрытый текст:
Этот текст скрытый. Вы должны оставить хотя бы одно сообщение в теме, чтобы его увидеть.


Отправлено XaeroX 14-08-2016 в 09:19:

Government-Man

Скрытый текст:
Этот текст скрытый. Вы должны оставить хотя бы одно сообщение в теме, чтобы его увидеть.

А теперь для С...

__________________

xaerox on Vivino


Отправлено Government-Man 14-08-2016 в 09:29:

Скрытый текст:
Этот текст скрытый. Вы должны оставить хотя бы одно сообщение в теме, чтобы его увидеть.


Отправлено XaeroX 14-08-2016 в 09:32:

Government-Man

Скрытый текст:
Этот текст скрытый. Вы должны оставить хотя бы одно сообщение в теме, чтобы его увидеть.

__________________

xaerox on Vivino


Отправлено nemyax 14-08-2016 в 09:38:

Цитата:
XaeroX писал:
функция foo, единственное предназначение которой - возврат указателя на саму себя

Пригодиться такое может, или это чисто упражнение на повозиться?


Отправлено XaeroX 14-08-2016 в 09:53:

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

__________________

xaerox on Vivino


Отправлено Дядя Миша 14-08-2016 в 11:23:

Раз вы все такие умные - давайте передавать указатель не на функцию, а на структуру, в которой указатель на функцию и рядом размер void в байтах.

Добавлено 14-08-2016 в 14:23:

Цитата:
nemyax писал:
Пригодиться такое может, или это чисто упражнение на повозиться?

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

__________________
My Projects: download page

F.A.Q по XashNT
Блог разработчика в телеграме

Цитата:

C:\DOCUME~1\C4C5~1\LOCALS~1\Temp\a33328if(72) : see declaration of 'size_t'


Отправлено XaeroX 14-08-2016 в 11:50:

Цитата:
Дядя Миша писал:
давайте передавать указатель не на функцию, а на структуру, в которой указатель на функцию и рядом размер void в байтах.

Давайте. Напиши компилируемый код.
Цитата:
Дядя Миша писал:
Потому что у практических задач зачастую не существует правильного решения.

Я, кстати, не говорил, что у этой задачи есть правильное решение.

__________________

xaerox on Vivino


Отправлено FreeSlave 14-08-2016 в 15:27:

Насколько я понимаю, вопрос задан под влиянием книги Саттера. Но даже он не даёт ответ, ибо вместо возвращения настоящего указателя предлагает возвращать обертку.

А ещё по идее нужно сделать, чтоб работали вот такие вещи:

code:
foo_t f = foo(); f(); (*f)(); foo_t f2 = f();


Что мне вовсе не представляется возможным.


Отправлено Дядя Миша 14-08-2016 в 15:30:

Цитата:
XaeroX писал:
Я, кстати, не говорил, что у этой задачи есть правильное решение.

но и практического применения тоже нет

__________________
My Projects: download page

F.A.Q по XashNT
Блог разработчика в телеграме

Цитата:

C:\DOCUME~1\C4C5~1\LOCALS~1\Temp\a33328if(72) : see declaration of 'size_t'


Отправлено XaeroX 14-08-2016 в 16:01:

Цитата:
FreeSlave писал:
Но даже он не даёт ответ, ибо вместо возвращения настоящего указателя предлагает возвращать обертку.

Он даёт ответ для плюсов, но не для чистого С.
Цитата:
FreeSlave писал:
Что мне вовсе не представляется возможным.

Я не вижу проблем. Вот навскидку написал код (СПОЙЛЕР!!!):
Скрытый текст:
Этот текст скрытый. Вы должны оставить хотя бы одно сообщение в теме, чтобы его увидеть.

Цитата:
FreeSlave писал:
вместо возвращения настоящего указателя предлагает возвращать обертку.

Ну так обвёртка (как я показал выше) может семантически выглядеть как "настоящий" указатель. Она и является указателем, если отбросить синтаксическую шелуху и посмотреть на её представление в памяти.

__________________

xaerox on Vivino


Отправлено XaeroX 16-08-2016 в 10:29:

Ладно, что-то все замолчали, выношу своё решение на критику:

Скрытый текст:
Этот текст скрытый. Вы должны оставить хотя бы одно сообщение в теме, чтобы его увидеть.


Критикуйте/опровергайте.

__________________

xaerox on Vivino


Временная зона GMT. Текущее время 20:27.
Показать все 19 сообщений этой темы на одной странице

На основе vBulletin версии 2.3.0
Авторское право © Jelsoft Enterprises Limited 2000 - 2002.
Дизайн и программирование: Crystice Softworks © 2005 - 2024