我目前正在使用llc将.ll文件转换为.s使用命令行的文件。然后我想获取这个文件,然后使用nasm从它创建一个可执行文件。虽然第一步似乎工作正常,但我无法让第二步工作。
原始文件被调用code.ll并包含以下代码:
define i32 @main() {
ret i32 0
}
Run Code Online (Sandbox Code Playgroud)
现在我使用 cmd.s通过键入以下内容来构建文件:
有限责任公司代码.ll
这工作正常并创建一个code.s包含以下代码的文件:
.def @feat.00;
.scl 3;
.type 0;
.endef
.globl @feat.00
@feat.00 = 1
.def _main;
.scl 2;
.type 32;
.endef
.text
.globl _main
.align 16, 0x90
_main: # @main
# BB#0:
xorl %eax, %eax
ret
Run Code Online (Sandbox Code Playgroud)
现在我想使用这段代码创建一个可执行文件,关于它的llc 文档告诉我:
然后,汇编语言输出可以通过本机汇编器和链接器来生成本机可执行文件。
因此,我 通过键入以下内容使用nasm(据我所知,它应该可以满足我的要求):
nasm 代码.s
这会产生以下错误列表:
code.s:1: error: attempt to …Run Code Online (Sandbox Code Playgroud) 我正在编写一个宏,它创建一个管理用户输入的结构。我现在用的包装箱bitflags和SDL2。Return是 key 的一个例子Return。
此宏获取所有可能输入的列表,然后
($($flag:ident = $value:expr;)+) => { ... }
Run Code Online (Sandbox Code Playgroud)
使用输入的名称创建一个新的位标志
bitflags!(
struct KeyType: u64 {
$(
const $flag = $value;// UPPER_CASE is the norm for globals: 'RETURN'
)+
}
);
Run Code Online (Sandbox Code Playgroud)使用Keycode枚举检查键是否被按下。
match event {
$(Event::KeyDown { keycode: Some(Keycode::$flag), .. } => {
self.flags.insert($flag);
},)+
_ => ()
}// All enum fields start with a capital letter: 'Return'
Run Code Online (Sandbox Code Playgroud)创建一个 getter 函数:
$(
pub fn $flag(&self) -> bool { // …Run Code Online (Sandbox Code Playgroud)我正在使用宏来实现特征作为我的库的一部分。此实现要求结构至少有一个附加字段。
pub trait Trait {
fn access_var(&mut self, var: bool);
}
macro_rules! impl_trait {
(for $struct:ident) => {
impl Trait for $struct {
pub fn access_var(&mut self, var: bool) {
self.var = var; // requires self to have a field 'var'
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
我想防止用户每次都必须添加这些附加字段。由于 Rust 编译器不允许在字段定义中使用宏(我没有这方面的来源,所以如果我错了,请纠正我),这样的事情是行不通的。
macro_rules! variables_for_trait {
() => {
var: bool,
}
};
struct Foo {
variables_for_trait!(); // error: expected ':' found '!'
additional_var: i64,
}
Run Code Online (Sandbox Code Playgroud)
我想我可以创建一个宏来启用这样的功能
bar!(Foo with additional_var: i64, other_var: u64);
Run Code Online (Sandbox Code Playgroud)
解决宏后看起来像这样:
pub …Run Code Online (Sandbox Code Playgroud) 我有一个包含不安全代码的结构,其方法如下:
use std::sync::Arc;
use std::thread;
#[derive(Debug)]
struct Foo<T> {
items: Vec<Box<(T, String)>>,
}
impl<T> Foo<T> {
pub fn add_element(&self, element: T, key: String) {
if !(self.items.iter().any( |i| i.1 == key)) {
let mut items = unsafe {change_mut(&(self.items))};
items.push(Box::new((element,key)));
}
}
}
unsafe fn change_mut<T>(x: &T) -> &mut T { // changes &self to &mut self
&mut *(x as *const T as *mut T)
}
fn main() {
let foo = Arc::new(Foo { items: vec!() });
let clone = foo.clone();
// …Run Code Online (Sandbox Code Playgroud) 这是我要存档的简化版本:
struct Foo<'a> {
boo: Option<&'a mut String>,
}
fn main() {
let mut foo = Foo { boo: None };
{
let mut string = "Hello".to_string();
foo.boo = Some(&mut string);
foo.boo.unwrap().push_str(", I am foo!");
foo.boo = None;
} // string goes out of scope. foo does not reference string anymore
} // foo goes out of scope
Run Code Online (Sandbox Code Playgroud)
这显然是完全安全的,foo.boo是None一次string去的范围了。
有没有办法告诉编译器?
我最近遇到了一个错误,只需通过更改即可解决
impl<'a> Foo<'a> {
fn foo(&'a self, path: &str) -> Boo<'a> { /* */ }
}
Run Code Online (Sandbox Code Playgroud)
至
impl<'a> Foo<'a> {
fn foo(&self, path: &str) -> Boo { /* */ }
}
Run Code Online (Sandbox Code Playgroud)
根据我的理解,这没有任何意义,因为我认为第二个版本与第一个使用了生命周期省略的版本完全相同。
如果我们为该方法引入了新的生命周期,那么根据nomicon的此示例似乎就是这种情况。
fn get_mut(&mut self) -> &mut T; // elided
fn get_mut<'a>(&'a mut self) -> &'a mut T; // expanded
Run Code Online (Sandbox Code Playgroud)
那么这和我的第一个代码片段之间有什么区别。