相关疑难解决方法(0)

什么是尾递归?

在开始学习lisp时,我遇到了尾递归这个术语.这究竟是什么意思?

language-agnostic algorithm recursion functional-programming tail-recursion

1602
推荐指数
27
解决办法
42万
查看次数

什么是尾部呼叫优化?

很简单,什么是尾部调用优化?更具体地说,任何人都可以显示一些可以应用的小代码片段,而不是在哪里,并解释为什么?

language-agnostic algorithm recursion tail-recursion tail-call-optimization

765
推荐指数
8
解决办法
15万
查看次数

哪个(如果有的话)C++编译器会进行尾递归优化?

在我看来,在C和C++中进行尾递归优化是完美的,但是在调试时我似乎永远不会看到表示此优化的帧堆栈.这有点好,因为堆栈告诉我递归的深度.但是,优化也会很好.

是否有任何C++编译器进行此优化?为什么?为什么不?

我如何告诉编译器这样做?

  • 对于MSVC:/O2/Ox
  • 对于海湾合作委员会:-O2-O3

如何在某种情况下检查编译器是否已完成此操作?

  • 对于MSVC,启用PDB输出以跟踪代码,然后检查代码
  • 对于GCC ..?

我仍然会建议如何确定编译器是否对某个函数进行了优化(尽管我发现它让人放心,Konrad告诉我假设它)

总是可以通过进行无限递归来检查编译器是否完成此操作,并检查它是否导致无限循环或堆栈溢出(我用GCC做了这个并且发现这-O2已经足够了),但我想成为能够检查我知道的某个功能无论如何都会终止.我很想有一个简单的方法来检查这个:)


经过一些测试,我发现析构函数破坏了进行优化的可能性.有时可能值得更改某些变量和临时值的范围,以确保它们在return语句开始之前超出范围.

如果在尾调用后需要运行任何析构函数,则无法进行尾调用优化.

c++ optimization tail-recursion

144
推荐指数
5
解决办法
4万
查看次数

通过分析程序集列表验证gcc/g ++中的编译器优化

我刚刚问了一个与编译器如何优化某些C++代码有关的问题,我正在寻找有关如何验证编译器是否已执行某些优化的任何问题.我试图查看用g ++(g++ -c -g -O2 -Wa,-ahl=file.s file.c)生成的汇编列表,可能会看到底层发生了什么,但输出对我来说太神秘了.人们使用什么技术来解决这个问题,是否有任何关于如何解释优化代码的汇编列表或特定于GCC工具链的文章的讨论这个问题的参考?

c c++ compiler-construction assembly micro-optimization

11
推荐指数
3
解决办法
6556
查看次数

g ++中尾部递归的问题

我正在用C++搞乱尾递归函数,而且我在使用g ++编译器时遇到了一些麻烦.

numbers[]大小超过几百个整数时,以下代码导致堆栈溢出.检查由g ++生成的汇编代码,表明twoSum_Helper正在call对自身执行递归指令.

问题是以下哪一项导致了这种情况?

  • 我忽略了下面的一个错误,它阻止了尾递归.
  • 我使用g ++时出错了.
  • g ++编译器中检测尾递归函数的缺陷.

我正在g++ -O3 -Wall -fno-stack-protector test.c通过MinGW和g ++ 4.5.0在Windows Vista x64上进行编译.

struct result
{
    int i;
    int j;
    bool found;
};

struct result gen_Result(int i, int j, bool found)
{
    struct result r;
    r.i = i;
    r.j = j;
    r.found = found;
    return r;
}

// Return 2 indexes from numbers that sum up to target.
struct result twoSum_Helper(int numbers[], int size, int target, int i, …
Run Code Online (Sandbox Code Playgroud)

c++ recursion functional-programming tail-recursion g++

11
推荐指数
1
解决办法
1320
查看次数

在GCC进行的每次优化后获取汇编代码?

来自维基百科上的优化编译器,

编译器优化通常使用一系列优化转换来实现,这些算法采用程序并对其进行转换以生成使用较少资源的语义上等效的输出程序.

和GCC有很多优化选择.

我想学习所生成的组件(一个-S具有不同的标志等进行编译时给出),每个优化GCC执行后-O1,-O2,-O3等.

我怎样才能做到这一点?

编辑:我的输入将是C代码.

c compiler-construction optimization assembly gcc

11
推荐指数
2
解决办法
4723
查看次数

递归开销 - 有多严重?

可能重复:
递归是否比循环更快?

大约15年前,我第一次接受C语言培训.我的雇主想要高度优化的代码来处理计算困难的任务.我记得不止一次被建议将递归重写为循环,即使是在昂贵的可读性方面,以避免"递归开销".正如我所理解的那样,递归开销是将数据推送到堆栈然后将其弹出所需的额外工作.

现在我用C,Python,Perl编写,有时用Java编写代码,我有时会想到递归.还有什么东西可以通过重写来获得吗?如果它们是尾递归怎么办?现代编译器让所有这些问题都没有实际意义吗?这些担忧是否与解释语言无关?

optimization recursion programming-languages tail-recursion interpreted-language

10
推荐指数
1
解决办法
7151
查看次数

c ++递归退出没有明显的原因

我使用递归编写了一个函数.事实证明,在测试时,该函数在没有任何明显原因的情况下被终止,而递归仍然在运行.

为了测试这个,我写了一个无限的递归.

在我的电脑上,此功能在约2秒后退出,最后一个输出约为327400.最后一个数字并不总是相同.

我使用的是Ubuntu Lucid Lynx,GCC编译器和Eclipse作为IDE.如果有人知道问题是什么以及我如何阻止程序退出,我会非常高兴.

#include <iostream>

void rek(double x){
    std::cout << x << std::endl;
    rek(x + 1);
}

int main(int argc, char **argv) {
    rek(1);
}
Run Code Online (Sandbox Code Playgroud)

c++ ubuntu recursion gcc infinite

5
推荐指数
1
解决办法
257
查看次数

为什么像C,Pascal这样的语言不能实现尾递归?

我在读SICP.其中一个脚注中提到:

使编译器生成尾递归代码似乎是一个简单的想法.但是大多数常用语言编译器(包括C和Pascal)都没有这样做,因此这些语言不能仅仅根据过程调用来表示迭代过程.这些语言中尾递归的难点在于它们的实现使用堆栈来存储过程参数和局部变量以及返回地址.


我无法理解为什么如果将堆栈用于过程参数,局部变量和返回地址,则无法实现尾递归.

c scheme pascal tail-recursion sicp

4
推荐指数
2
解决办法
775
查看次数

如何针对内存使用优化GCC编译?

我正在开发一个应尽可能少使用内存的库(我不关心其他任何东西,比如二进制大小或速度优化).

我可以使用任何GCC标志(或任何其他与GCC相关的选项)吗?我应该避免某种程度的-O*优化吗?

c gcc

3
推荐指数
1
解决办法
5418
查看次数