Название вопроса может быть немного странным, но дело в том, что, насколько мне известно, нет ничего, что вообще говорило бы против оптимизации хвостового вызова. Однако, просматривая проекты с открытым исходным кодом, я уже сталкивался с несколькими функциями, которые активно пытаются помешать компилятору выполнять оптимизацию хвостового вызова, например, реализация CFRunLoopRef, в котором полно таких хаков. Например:
static void __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__() __attribute__((noinline));
static void __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__(CFRunLoopObserverCallBack func, CFRunLoopObserverRef observer, CFRunLoopActivity activity, void *info) {
if (func) {
func(observer, activity, info);
}
getpid(); // thwart tail-call optimization
}
Я хотел бы знать, почему это так важно, и есть ли случаи, когда я, как нормальный разработчик, должен помнить об этом? Например. Есть ли распространенные ошибки с оптимизацией хвостового вызова?
__asm__ __volatile__ ( "" : : "memory" );
было бы намного дешевле сделать это. - person R.. GitHub STOP HELPING ICE   schedule 29.05.2012__asm__ volatile
вместо системного вызова. Я отредактирую вопрос, когда найду их снова, но похоже, что это либо более распространенный страх или проблема, которую они пытаются избежать - person JustSid   schedule 29.05.2012__attribute__((noinline))
тоже выглядит подозрительно. Может быть, автор зависит от очень специфического поведения среды выполнения в отношении настройки стека? - person Niklas B.   schedule 29.05.2012getpid()
не используется, не может ли его удалить информированный оптимизатор (посколькуgetpid
- это функция, которая, как известно, не имеет побочных эффектов), что позволяет компилятору в любом случае выполнять оптимизацию хвостового вызова? Это кажется действительно хрупким механизмом. - person luiscubal   schedule 29.05.2012x = getpid(); x = getpid();
то же самое, чтоx = getpid();
, поэтому его действительно можно оптимизировать. Тот факт, что результат кэшируется и первый раз попадает в ОС, не имеет значения, поскольку нетcount_number_of_times_getpid_was_called
функции. Оптимизатору не обязательно предполагать, что вызов имеет побочные эффекты. Если результат всегда один и тот же, он может быть в каком-то белом списке функций, который, как известно, безопасен и поэтому может быть оптимизирован. - person luiscubal   schedule 30.07.2013x = getpid(); x = getpid();
можно оптимизировать доgetpid(); x=getpid();
- person Chris   schedule 30.07.2013__attribute__ ((pure))
, они могли бы. Он не оптимизирует его, поэтому я предполагаю, что у него нет этого атрибута. Обратите внимание, что если бы у него был атрибут в заголовке, тип связи не имел бы значения. А что им мешает добавить в шапку? Если стандарт гарантирует, что getpid всегда возвращает одно и то же значение, тогда ответ - ничего - и если вы измените реализацию, это ваша проблема. - person luiscubal   schedule 30.07.2013