我们在C++中有一个很大的代码库,在一个小的重构(一个类添加并重写了一些相关的方法)之后,我们开始在GCC 3和4上获得链接器错误.链接器错误特别是"缺少对非虚拟thunk的引用"在我们的大型SDK中继承类的小型示例程序.
搜索网络并没有提供许多暗示,除了一些似乎已经解决的旧GCC错误之外.
问题的属性似乎是:
-O2
class Foo: public A, public B {}
来class Foo: public B, public A {}
虚拟继承仅出现在一个非常常用的基类中,用于引用计数.我已经证实,这个类的每个用法都是虚拟公共的,而不仅仅是公共继承.
显然,摆弄继承顺序并不能解决问题.还有什么呢?
什么是与EXE文件中用于导入外部DLL中使用的函数的导入地址表相关的thunk表?
这个thunk表只是一个包含"Thunks"到其他函数的表吗?
这是一段代码,它给了我一个StackOverflowError
(从我的代码库中的实际示例中简化):
( ->> (range 3000)
(mapcat #(concat [0] (take 100 (repeat %))))
(reduce (constantly nil))
(count))
Run Code Online (Sandbox Code Playgroud)
(注:此代码是不是为了做除了说明问题或返回零任何东西.)
我可以通过以下任何步骤"拯救"它:
reduce
行[0]
到 '(0)
(take 100000000)
在mapcat
和之间的任何点添加(或任何整数)count
.我基本上对这种行为感到困惑(特别是#2).我很感激任何意见.
(我有一种感觉这可能与为什么reduce在Clojure中给出一个StackOverflowError有关?但是我不知道如何 - 所以如果它是相关的,我会理解为什么会这样解释.)
在Haskell中,您可以拥有无限列表,因为它不完全计算它们,它使用thunk.我想知道是否有一种方法可以序列化或以其他方式将一个数据保存到文件中.例如,假设您有一个列表[0..]
.然后,你做一些处理就可以了(我最感兴趣tail
和(:)
,但它应该支持这样做filter
或map
为好.)这里是有点什么,我找的一个例子.
serial::(SerialThunk a)=>a->serThunk
serialized = serial ([0..] :: [Int])
main=writeToFile "foo.txt" serialized
Run Code Online (Sandbox Code Playgroud)
和
deserial::(SerialThunk a)=>serThunk->a
main=do
deserialized <- readFromFile "foo.txt" :: IO [Int]
print $ take 10 deserialized
Run Code Online (Sandbox Code Playgroud) 我的理解是,foldl
和foldr
执行,如:
foldl f a [1..30]
=> (f (f (f ... (f a 1) 2) 3) ... 30)
和
foldr f a [1..30]
=> (f 1 (f 2 (f 3 (f ....(f 30 a)))))..)
所以.. foldr (&&) False (repeat False)
可以shortciruit,因为外部f
看到(&&) False ((&&) False (....))
第一个参数看起来是假的,并且不需要评估第二个参数(这是一个大的thunk).
所以会发生什么
andFn :: Bool -> Bool -> Bool
andFn _ False = False
andFn x True = x
Run Code Online (Sandbox Code Playgroud)
和
foldl andFn True (repeat False) -- =>
-- (andFn …
Run Code Online (Sandbox Code Playgroud) 我知道两者都是返回函数的函数.
到目前为止,我使用thunk的经验一直在使用它们返回函数而不仅仅是动作对象,这样我就可以使用异步请求Redux
.
闭包是一个高阶函数(HOF)的实现,以便为私有变量创建一个新的范围......对吗?HOFs的其他例子包括map
,reduce
和filter
.
有没有其他明确定义两者之间差异的东西?
谢谢.
javascript functional-programming thunk higher-order-functions redux
我在实时应用程序中发生了崩溃,但在开发过程中无法重现它。日志来自 Crashlytics。
我无法弄清楚崩溃的原因以及如何修复。
有什么帮助吗?
崩溃日志
Crashed: com.apple.main-thread
0 MyApp 0x100f5d538 closure #2 in MyViewController.buttonTapped(_:) + 4308292920 (<compiler-generated>:4308292920)
1 MyApp 0x101250a98 thunk for @escaping @callee_guaranteed (@guaranteed UIAlertAction) -> () + 4311386776 (<compiler-generated>:4311386776)
2 UIKitCore 0x19cb4aed0 -[UIAlertController _invokeHandlersForAction:] + 108
3 UIKitCore 0x19cb4b82c __103-[UIAlertController _dismissAnimated:triggeringAction:triggeredByPopoverDimmingView:dismissCompletion:]_block_invoke.458 + 28
4 UIKitCore 0x19cdfcfe0 -[UIPresentationController transitionDidFinish:] + 952
5 UIKitCore 0x19ce0176c __56-[UIPresentationController runTransitionForCurrentState]_block_invoke.503 + 208
6 UIKitCore 0x19cf055a8 -[_UIViewControllerTransitionContext completeTransition:] + 100
7 UIKitCore 0x19d981d90 -[UIViewAnimationBlockDelegate _didEndBlockAnimation:finished:context:] + 588
8 UIKitCore 0x19d955c70 -[UIViewAnimationState sendDelegateAnimationDidStop:finished:] + 244 …
Run Code Online (Sandbox Code Playgroud) 如何在x86和x64上使用任意(固定)数量的参数来查找任意函数?
(我不需要浮点数,SSE等.参数都是整数或指针.)
提问这个问题有点奇怪,因为我的代码似乎不应该起作用,但确实如此,虽然我没有抱怨,但我想确认原因?大声笑
简单地说,我有一个C++本机DLL(根本没有CLR /托管支持),它接受来自C#代码的回调.本机端存储stdcall回调函数,该函数由C#端提供.我一直认为回调METHOD(在C#中)必须是静态的,但是非静态和lambda表达式两种工作都很简单!?"this"指针是如何从本机代码编组的?我一直以为本机代码只存储非实例函数指针?
现在,我确实找到了一篇文章,其中一些人发出了IL代码,以便在本地和非静态托管回调之间"桥接".我还注意到了这种折旧的方法:"Marshal.GetUnmanagedThunkForManagedMethodPtr()".不再支持该方法,我假设它意味着它是内置的?
问题摘要:
现在通过发送IL代码将thunking本地构建到.NET中吗?如果是这样,在什么版本的.NET中,这会被本机支持?
Mono也支持隐含的"thunking"吗?
当为托管回调发出IL时,当thunk引用的实例被删除时会发生什么?是否删除了IL,或者这可能会导致内存"泄漏"?
谢谢.
以下源代码在 VC 中生成警告 C4407,并且编译器确实生成了不正确的代码。
struct A1 {
int a1;
};
struct A2 {
int a2;
};
struct B: A1, A2 {
void f() {
std::cout << this << '\n';
}
};
int main() {
B b = B();
void (B::*pb)() = &B::f;
void (A2::*pa)() = (void (A2::*)())pb; // performs static_cast actually
std::cout << (std::uintptr_t&)pb << '\n';
std::cout << (std::uintptr_t&)pa << '\n';
B* pB = &b;
A2* pA = pB;
std::cout << pB << '\n';
std::cout << pA << '\n';
(pB->*pb)(); …
Run Code Online (Sandbox Code Playgroud)