在我看来,在C和C++中进行尾递归优化是完美的,但是在调试时我似乎永远不会看到表示此优化的帧堆栈.这有点好,因为堆栈告诉我递归的深度.但是,优化也会很好.
是否有任何C++编译器进行此优化?为什么?为什么不?
我如何告诉编译器这样做?
/O2或/Ox-O2或-O3如何在某种情况下检查编译器是否已完成此操作?
我仍然会建议如何确定编译器是否对某个函数进行了优化(尽管我发现它让人放心,Konrad告诉我假设它)
总是可以通过进行无限递归来检查编译器是否完成此操作,并检查它是否导致无限循环或堆栈溢出(我用GCC做了这个并且发现这-O2已经足够了),但我想成为能够检查我知道的某个功能无论如何都会终止.我很想有一个简单的方法来检查这个:)
经过一些测试,我发现析构函数破坏了进行优化的可能性.有时可能值得更改某些变量和临时值的范围,以确保它们在return语句开始之前超出范围.
如果在尾调用后需要运行任何析构函数,则无法进行尾调用优化.
请考虑以下代码:
void foo()
{
{
CSomeClass bar;
// Some code here...
goto label;
// and here...
}
label:
// and here...
}
Run Code Online (Sandbox Code Playgroud)
bar的析构函数会被调用吗?
任务很简单:我们有一个类型列表(即using list = std::tuple<A, B, C, ...>;),我们希望根据运行时已知的索引调度其内容.通过"dispatch"我的意思是调用一个模板化的处理程序,由该列表中的类型参数化.switch手动编写很容易:
template <class... Args>
auto dispatch(size_t i, Args&& ...args)
{
switch (i) {
case 0: return handler<typename std::tuple_element<0, list>::type>(std::forward<Args>(args)...);
...
}
}
Run Code Online (Sandbox Code Playgroud)
但这很乏味,容易出错,而且很无聊.我正在寻找一种方法来强制编译器从更紧凑和简洁的定义中做到这一点.
我想要获得与手动开关相同或非常接近的结果.因此,生成函数指针表(如此处)并不是一个理想的解决方案(我不想为处理程序完全无法使用的情况引入函数调用).
到目前为止,我发现了两种方法:
无法递归(感谢Horstling)
template <size_t N>
struct dispatch_helper
{
template <class... Args>
static R dispatch(size_t i, Args&& ...args)
{
if (N == i)
return handler<typename std::tuple_element<N, list>::type>(std::forward<Args>(args)...);
return dispatch_helper<N+1>::dispatch(i, std::forward<Args>(args)...);
}
};
template <>
struct dispatch_helper<200>
{
template <class... Args>
static R dispatch(size_t …Run Code Online (Sandbox Code Playgroud)在Clang API中,有GotoStmt和IndirectGotoStmt。关于这两种goto陈述之间的区别,几乎没有解释。我知道这goto label;是什么声明。但是什么是间接goto语句?我想知道C / C ++代码上下文中的含义,而不仅仅是Clang。拥有间接goto语句在语法上意味着什么?您可以提供一个代码示例吗?
编辑:以下问题很有趣。
有没有办法在标签名称的位置使用变量调用goto语句?
我正在寻找类似的东西(这对我不起作用):
// std::string or some other type that could represent a label
void callVariable(std::string name){
goto name;
}
int main(){
first:
std::cout << "Hi";
callVariable(first);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我实际上并没有使用它,我对学习更感兴趣.
c++ ×5
goto ×3
c ×1
c++11 ×1
c++14 ×1
clang ×1
destructor ×1
gcc ×1
llvm-clang ×1
optimization ×1
variables ×1