为了确定我是否可以/应该使用 Rust 而不是默认的 C/C++,我正在研究各种边缘情况,主要考虑到这个问题:在 0.1% 的情况下,它确实很重要,我总能得到编译器输出与 gcc 一样好(具有适当的优化标志)?答案很可能是否定的,但让我们看看......
Reddit上有一个相当特殊的示例,研究无分支排序算法的子例程的编译器输出。
这是基准 C 代码:
#include <stdint.h>
#include <stdlib.h>
int32_t* foo(int32_t* elements, int32_t* buffer, int32_t pivot)
{
size_t buffer_index = 0;
for (size_t i = 0; i < 64; ++i) {
buffer[buffer_index] = (int32_t)i;
buffer_index += (size_t)(elements[i] < pivot);
}
}
Run Code Online (Sandbox Code Playgroud)
这是带有编译器输出的godbolt 链接。
Rust 的第一次尝试如下所示:
pub fn foo0(elements: &Vec<i32>, mut buffer: [i32; 64], pivot: i32) -> () {
let mut buffer_index: usize = 0;
for i in 0..buffer.len() {
buffer[buffer_index] …Run Code Online (Sandbox Code Playgroud) 我正在阅读ARM发布的SVE白皮书,并发现了令我印象深刻的东西(在非SVE示例中):
mov x8, xzr
Run Code Online (Sandbox Code Playgroud)
我不知道这个xzr寄存器是什么,所以我查了一下,发现ARM的一些内容,说它在很多情况下都是零的同义词.
所以看起来x8它被初始化为零,这是有道理的,因为它在循环之前执行,x8用作循环计数器.
我不明白的是,为什么不使用文字0而不是xzr?例如:
mov x8, 0
Run Code Online (Sandbox Code Playgroud)
总而言之,我的问题是:为什么可以使用xzr寄存器而不是文字0?
我有一个用于boost::signals2组件之间通信的应用程序.我正在尝试使用它的自动连接管理功能slot_type(...).track(weak_ptr).
问题:
在我的整个程序中,std::shared_ptr使用..track期待一个boost::weak_ptr,我提供一个std::weak_ptr.
这是我得到的确切错误:
cannot convert argument 1 from 'std::weak_ptr<_Ty>' to 'const boost::weak_ptr<void> &'
Run Code Online (Sandbox Code Playgroud)
这有解决方法吗?或者我误解了这个问题?
来自C++,我对new在C#中使用关键字感到困惑.
我知道它不像C++一样工作new,因为你不必手动控制对象的生命周期,因为C#有垃圾收集.
但是,当阅读其他人的C#代码时,我会注意到代码片段1中的语句.如果new在代码片段2 中完全避免使用它会不会更容易?
片段1
Foo fooInstance = new Foo();
Run Code Online (Sandbox Code Playgroud)
片段2
Foo fooInstance;
Run Code Online (Sandbox Code Playgroud)
我的问题是,代码段1和代码段2之间有什么区别,为什么我更喜欢一个呢?
我正在尝试学习 x86_64 汇编,并使用 GCC 作为我的汇编程序。我正在使用的确切命令是:
gcc -nostdlib tapydn.S -D__ASSEMBLY__
Run Code Online (Sandbox Code Playgroud)
我主要使用 gcc 作为它的预处理器。这是tapydn.S:
.global _start
#include <asm-generic/unistd.h>
syscall=0x80
.text
_start:
movl $__NR_exit, %eax
movl $0x00, %ebx
int $syscall
Run Code Online (Sandbox Code Playgroud)
这会导致分段错误。我相信问题出在以下几行:
movl $__NR_exit, %eax
Run Code Online (Sandbox Code Playgroud)
我使用__NR_exit它是因为它比一些神奇的数字更具描述性。但是,我对它的使用似乎是不正确的。我相信情况确实如此,因为当我将有问题的行更改为以下内容时,它运行良好:
movl $0x01, %eax
Run Code Online (Sandbox Code Playgroud)
进一步支持这一思路的是以下内容usr/include/asm-generic/unistd.h:
#define __NR_exit 93
__SYSCALL(__NR_exit, sys_exit)
Run Code Online (Sandbox Code Playgroud)
我预计 __NR_exit 的值为 1,而不是 93!显然我误解了它的目的,因此误解了它的用法。据我所知,我很幸运能在$0x01案例中工作(很像 C++ 中的未定义行为),所以我一直在挖掘......
接下来,我寻找sys_exit. 我找不到。我尝试使用它如下(有和没有前面的 $):
movl $sys_exit, %eax
Run Code Online (Sandbox Code Playgroud)
这不会链接:
/tmp/cc7tEUtC.o: In function `_start':
(.text+0x1): undefined reference to `sys_exit'
collect2: error: ld returned 1 exit …Run Code Online (Sandbox Code Playgroud) 假设你有一些代码推送到这样的队列:
template <typename T>
void submitJobToPool(T callable)
{
someJobQueue.push(callable)
}
Run Code Online (Sandbox Code Playgroud)
......以及后来:
template <typename T>
void runJobFromPool(T callable)
{
auto job = someJobQueue.pop();
job();
}
Run Code Online (Sandbox Code Playgroud)
现在想象一下,由于job()调用内部的一些错误,代码崩溃了.如果提交的作业是普通函数,则调用堆栈可能如下所示:
void myFunction() 0x345678901
void runJobFromPool() 0x234567890
int main(int, char**) 0x123456789
Run Code Online (Sandbox Code Playgroud)
很容易看出这里崩溃了什么功能.如果它是一个仿函数,它将是相似的,但operator()在某处(忽略内联).然而,对于一个lambda ......
void lambda_a7009ccf8810b62b59083b4c1779e569() 0x345678901
void runJobFromPool() 0x234567890
int main(int, char**) 0x123456789
Run Code Online (Sandbox Code Playgroud)
这不是那么容易调试.如果在发生调试器时附加了调试器,或者核心转储可用,则可以使用该信息来导出哪个lambda崩溃,但该信息并不总是可用.据我所知,反汇编是确定从此崩溃的几种方法之一.
我必须做的更好的想法是:
addr2line平台支持的工具.这有时有效,有时不行.第四个选项听起来很有希望,所以我做了一些调查,但找不到任何东西.如果它很重要,我可用的编译器是clang ++ 5.0和MSVC 19(Visual Studio 2015).
我的问题是,有哪些其他工具/技术可以帮助将带有lambda函数的callstack映射到相应的源代码行?
我有一个带字符串向量的函数,我在向量中有一系列字符串向量.
我想循环遍历将每个字符串向量传递给新线程的向量.
for (vector<vector<string> >::iterator it = vecstringvec.begin() ;
it != vecstringvec.end(); ++it){
threadvector.push_back(thread(func, *it));
}
Run Code Online (Sandbox Code Playgroud)
基本上是上面的,除了上面的不起作用(编译错误).我相信我需要一个传递的std :: ref来传递,但我不确定,或者如何使用迭代器来做到这一点.
完整错误:
/usr/include/c++/4.8/functional: In instantiation of ‘struct std::_Bind_simple<void (*(std::vector<std::basic_string<char> >, std::reference_wrapper<std::vector<std::basic_string<char> > >))(std::vector<std::basic_string<char> >&, std::vector<std::basic_string<char> >&)>’:
/usr/include/c++/4.8/thread:137:47: required from ‘std::thread::thread(_Callable&&, _Args&& ...) [with _Callable = void (&)(std::vector<std::basic_string<char> >&, std::vector<std::basic_string<char> >&); _Args = {std::vector<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > >&, std::reference_wrapper<std::vector<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >}]’
prog.cpp:199:55: required from here
/usr/include/c++/4.8/functional:1697:61: error: no type named …Run Code Online (Sandbox Code Playgroud) 我今天一直在学习CRTP(奇怪的重复模板模式),并相信我理解得很好.
但是,在我看到的示例中,状态存储在派生类型中,即使基类型依赖于它们的存在.对我来说,这似乎是不合逻辑的,成员变量应该在基类型中,因为它的功能依赖于它们.
这是我正在谈论的一个简单例子:
template <typename DerivedType>
class Base{
public:
int calculate() {
return static_cast<DerivedType&>(*this).x + static_cast<DerivedType&>(*this).y;
}
};
class Derived : Base<Derived>{
public:
int x; // ignore the fact that these aren't initialised for simplicity
int y;
};
Run Code Online (Sandbox Code Playgroud)
我的问题是:
我是否正确地认为成员x并且y在基类型方面会更好?如果没有,为什么?
我有一个输出值的随机数生成器(0, 1],但是我需要将输出提供给一个在0或1处返回无穷大的函数.如何在(0, 1)没有任何分支的情况下对生成的数字进行后处理,因为这是为了在GPU上执行?
我想一种方法是添加一个小常数然后取值mod 1.换句话说,生成from (?, 1 + ?],变成了[?, 1).有没有更好的办法?应该?是什么?
我有一个模式匹配其参数的函数,它是string:
let processLexime lexime
match lexime with
| "abc" -> ...
| "bar" -> ...
| "cat" -> ...
| _ -> ...
Run Code Online (Sandbox Code Playgroud)
这按预期工作.但是,我现在试图通过表达"匹配string仅包含以下字符" 来扩展它.在我的具体示例中,我希望只匹配包含数字的任何内容.
我的问题是,我怎样才能在F#中表达这一点?我更喜欢在没有任何库的情况下这样做FParsec,因为我主要是为了学习目的而这样做.