散列消耗包括在内存中仅保留给定对象的一个副本; 也就是说,如果两个对象在语义上相等(相同的内容),那么它们应该在物理上相等(内存中的相同位置).该技术通常通过保持全局散列集并仅在它们不等于散列集中的对象时创建新对象来实现.
另一个要求是,如果除了哈希表之外的任何东西都没有引用哈希表中的对象,那么它们应该是可收集的.否则说,哈希表应该包含弱引用.
由于需要有恒定的时间,因此需要进行浅层,散列和相等测试,因此问题更加复杂; 因此,对象具有唯一标识符,当将新对象添加到表中时,该标识符会递增.
我有一个工作实现,它使用System.Collections.Generic.Dictionary<key, node>where key元组给出一个浅层的节点摘要(适用于默认的散列和相等测试)并且node是对象.唯一的问题是Dictionary保持对节点的强引用!
我可以使用a Dictionary,WeakReference但这不会释放指向悬空引用的键.
有些人主张使用,System.Runtime.CompilerServices.ConditionalWeakTable但是这个类似乎反过来了:它在收集密钥时释放了值,而我需要在收集值时释放密钥.
可以尝试使用,System.Runtime.CompilerServices.ConditionalWeakTable<node, node>但我需要自定义散列和相等测试...并且ConditionalWeakTable记录不使用GetHashCode()虚方法,而是使用默认的散列函数.
因此,我的问题是:是否有一些相当于Dictionary保持对值的弱引用并在引用变为悬空时释放键?
在OCaml中,拥有以下内容是合法的.mli:
val f : 'a -> 'a
val g : 'a -> 'a
Run Code Online (Sandbox Code Playgroud)
并且.ml:
let f x = x
let g = f
Run Code Online (Sandbox Code Playgroud)
然而在F#中,这被拒绝了:
eta_expand.ml(2,5): error FS0034: Module 'Eta_expand' contains
val g : ('a -> 'a)
but its signature specifies
val g : 'a -> 'a
The arities in the signature and implementation differ. The signature specifies that 'g' is function definition or lambda expression accepting at least 1 argument(s), but the implementation is a computed …Run Code Online (Sandbox Code Playgroud) OCaml的Hindley-Milner类型系统不允许使用impredicative多态(àlaSystem-F),除非通过最近的记录类型扩展.这同样适用于F#.
然而,有时希望将用不可预测的多态性(例如Coq)编写的程序翻译成这样的语言.Coq对OCaml的提取器的解决方案是(谨慎地)使用Obj.magic,这是一种通用的不安全转换.这是因为
是否有可能在F#中做类似的事情?
我想使用autotools构建系统将软件编译为LLVM bitcode; 也就是说,我希望最后获得的可执行文件是LLVM bitcode,而不是实际的机器代码.
(目标是能够在整个程序上运行LLVM bitcode分析工具.)
我已经尝试过CC="clang -emit-llvm -use-gold-plugins"为configure脚本指定和变种,但无济于事.总会出现问题(例如,包构建.a静态库,链接器拒绝这些库).
在我看来,正确的方法是LLVM bitcode应该是一个交叉编译目标.要设置--host=,但没有这样的标准目标(即使Knuth的MMIX有目标).
到目前为止,我已经使用过kludges,例如手动编译CC="clang -emit-llvm -use-gold-plugins"和运行链接线(使用llvm-ld或llvm-link).这适用于简单的包,例如grep.
我想要一个健壮的方法,并且适用于大多数(如果不是全部)配置脚本,包括存在中间.a文件或中间目标时.
当运行使用gcc-4.8.1编译的代码时,我在x86(32位)平台上发生了一个神秘的总线错误-march=pentium4.我将问题追溯到SSE指令:
movdqa %xmm5,0x50(%esp)
Run Code Online (Sandbox Code Playgroud)
esp = 0xbfffedac.movdqa要求地址为16字节对齐,这不是这种情况,因此总线错误.
如果使用-march=native(这是Core-i3处理器)进行编译,则不会出现此问题.
据我所知,Linux/x86上唯一保证的堆栈对齐是4字节.因此,movdqa即使存在movdqu可能未对齐访问的指令,代码生成器应该选择使用而不进行某种对齐检查似乎很奇怪.
所以,这看起来像gcc中有一个bug.
我不是SSE和x86 ABI的专家,在发送错误报告之前我会很感激.
我的程序通过分而治之的方法搜索问题的解决方案(任何解决方案),使用递归和实现RecursiveTasks:我为该部门的第一个分支派一个任务,然后递归到第二个分支:如果第二个分支找到了解决方案,然后我取消了第一个分支,否则我等待它的结果.
这可能不是最佳的.如果找到解决方案,一种方法是针对任何已启动的任务抛出异常.但是,我将如何取消所有已启动的任务?取消任务是否也取消所有子任务?
考虑以下 C 程序:
\ndouble local_array[10];\n/* local computations */\nf(); // f() cannot modify the local_array since the local_array has not escaped\nlocal_array[i] += 5.0;\nRun Code Online (Sandbox Code Playgroud)\n如果f()已知正常返回,则可以local_array[i] += 5.0;在调用之前移动,也许是为了效率(可以将加载 - 浮动添加 - 存储序列与前面的计算混合在一起)。
然而,如果f()不知道正常返回,则这对于标准而言可能是非法的。事实上,如果f()打印一条错误消息并退出,那么在它之前进行访问local_array[i]可能会失败(由于 的值不正确而导致错误的指针i),这将是危险的。我们无法知道是否p指向有效的、可写的内存。也许f()执行排除无效值的检查p。
所以我的问题是:有没有办法告诉编译器(也许是 gcc 或 clang)函数总是正常返回?
\n有一个nothrow属性,但似乎略有不同。
这样的属性将是 的“对偶” noreturn,这意味着函数永远不会返回。
如果你想知道这是怎么回事:PostgresSQL bug #616180是关于旧版本的gcc假设,他们可以在终止程序执行的函数调用之前对捕获指令进行类似的移动(由于检测到内部错误)。我认为gcc所做的事情是不正确的\xe2\x80\xa6 但是那么如何才能告诉它允许它执行这样的优化呢?
从Coq中提取的Ocaml代码包括(在某些情况下)定义的类型__和函数__,如下所示:
type __ = Obj.t
let __ = let rec f _ = Obj.repr f in Obj.repr f
Run Code Online (Sandbox Code Playgroud)
文档说,在过去,这种类型被定义为unit(因此__可以被视为()),但存在(罕见的)类型__的值应用于类型的值的情况__.
__使用Obj来自OCaml 的模块的未记录的函数,但似乎所定义的本质上是一个完全多态的函数,它吃掉它的所有参数(无论它们的数量是多少).
是否存在一些关于__无法消除的情况的文档,并且这种类型的值应用于相同类型的值,既来自理论(构造Coq术语,其中消除是不可能的),也来自实际的(表明发生这种情况的现实情况) ) 观点看法?
考虑以下程序
\nextern const int foo;\nextern void blah(void);\n\nint toto(void) {\n int x = foo;\n blah();\n int y = foo;\n return x + y;\n}\nRun Code Online (Sandbox Code Playgroud)\narm-linux-gnueabihf-gcc -std=c99 -O2 -fno-pic -S extern_const2.c将其编译为
toto:\n @ args = 0, pretend = 0, frame = 0\n @ frame_needed = 0, uses_anonymous_args = 0\n movw r3, #:lower16:foo\n movt r3, #:upper16:foo\n push {r4, lr}\n ldr r4, [r3]\n bl blah\n lsls r0, r4, #1\n pop {r4, pc}\nRun Code Online (Sandbox Code Playgroud)\n请注意,foo被读取一次,然后左移 1,这意味着假设gcc其值在函数调用期间保持不变。观察到类似的行为 …