我不能想到在规范中也有尾调用优化的真正的RAII语言,但我知道许多C++实现可以作为特定于实现的优化来实现.
这给那些那些实现了一个问题:因为析构函数,并在自动变量的作用域结束时被调用不是由一个单独的垃圾收集例程,是不是违反TCO的约束,递归调用必须在最后的指令功能结束?
例如:-
#include <iostream>
class test_object {
public:
test_object() { std::cout << "Constructing...\n"; }
~test_object() { std::cout << "Destructing...\n"; }
};
void test_function(int count);
int main()
{
test_function(999);
}
void test_function(int count)
{
if (!count) return;
test_object obj;
test_function(count - 1);
}
Run Code Online (Sandbox Code Playgroud)
"构建......"将写入999次,然后"破坏......"再写999次.最终,test_object在展开之前将自动分配999个实例.但假设一个实现有TCO,那么1000个堆栈帧是存在还是仅存在1?
递归调用之后的析构函数是否与事实上的TCO实现要求相冲突?
所以我们都听说过不使用register行,其理由是尝试优化编译器是一个愚蠢的错误.
register据我所知,实际上并没有说明有关CPU寄存器的任何信息,只是不能间接引用给定的变量.我猜测它通常被称为过时,因为编译器可以自动检测到缺少寻址,从而使这种优化变得透明.
但是如果我们对这个论点很坚定,那么它不能用C中的每个优化驱动关键字来衡量吗?为什么我们使用inline和C99一样restrict?
我认为像锯齿这样的东西很难甚至不可能推断出一些优化,那么在我们开始进入Sufficiently Smart Compiler领域之前,我们会在哪里划线?
在填充编译器优化信息并假设它知道它在做什么之间,应该在C和C++中绘制线应该放在哪里?
编辑:Jens Gustedt指出,我对C和C++的混淆是不正确的,因为其中两个关键字具有语义差异,而标准C++中不存在一个.我register在C++中有一个很好的链接,如果我找到它我会添加...
Objective-C/ARC /内存管理问题已经针对SO进行了死亡,但这个问题与现有问题略有不同.
我一直在尝试将Objective-C与GNUStep和Clang一起使用.我已经下载了现代Objective-C功能所需的库,如ARC; 块工作和@autoreleasepool编译器接受s以及相关的编译器标志.AppKit GUI工具包可以工作,队列调度程序也可以.
我的理解是,如果正确的话,alloced对象会自动设置为在退出@autoreleasepool"父"堆栈帧时释放,并且释放会减少引用计数.然而,编译器不会哀叹手动[super dealloc]和容忍手动autoreleases和releases,这意味着ARC甚至没有接通.
有人可能会想到谷歌搜索GNUStep ARC ~enable会产生一些我错过的编译器标志,但事实并非如此.
这是一些示例代码.它是C99 bool的多维数组的对象包装器,它被malloc编入内部init和free内部dealloc,我收集的是deallocARC代码中为数不多的合法用途之一.注意dealloc的puts是不能在@autoreleasepool结束后,被称为尽管有仅是在它创造了一个单一的参考.一本手册,release或者说autorelease很有效.
#import <stdbool.h>
#import <stdio.h>
#import <stdlib.h>
#import <Foundation/Foundation.h>
@interface Area : NSObject {
bool *area;
size_t width, height;
}
- (id) initWithWidth:(size_t)aWidth height:(size_t)aHeight;
- (void) dealloc;
- (void) display;
@end
@implementation Area
- …Run Code Online (Sandbox Code Playgroud) memory-management objective-c autorelease gnustep automatic-ref-counting
我正在寻找一种在Haskell中动态定义函数的方法,或者对于Haskell的惯用等价,我显然不知道.
场景如下:我有一个tagWithAttrs函数,它根据提供的String参数生成新函数.定义看起来像这样:
tagWithAttrs :: String -> ([(String, String)] -> [String] -> String)
tagWithAttrs tagName = [...] -- Implementation ommited to save room.
h1 :: [(String, String)] -> [String] -> String
h1 = tagWithAttrs "h1"
main :: IO ()
main = putStrLn $ h1 [("id", "abc"), ("class", "def")] ["A H1 Test"]
-- Should display '<h1 id="abc" class="def">A H1 Test</h1>'.
Run Code Online (Sandbox Code Playgroud)
到现在为止还挺好.但是我分配的行h1是其中之一,因为我必须为我定义的每个HTML标记执行此操作.在Python中,我循环遍历HTML标记名称列表,将每个相应的结果插入tag_with_attrs到返回的字典中globals().简而言之,我将动态地在符号表中插入新条目.
这个成语的Haskell等价是什么?
顺便说一句,我完全清楚我正在复制已经有HTML标签的许多现有库的工作.我正在做一个玩具项目,仅此而已:)
编辑:一些发布的解决方案建议仍然依赖于逐个定义最终结果标记函数的机制.这违反了DRY,否则我就会如何做到这一点.这是DRY违规,我正试图支持.
haskell functional-programming function higher-order-functions
c++ ×2
autorelease ×1
c ×1
function ×1
gnustep ×1
haskell ×1
objective-c ×1
optimization ×1
performance ×1
raii ×1
recursion ×1