实际上,使用此命令无法使用 Clang 编译以下代码:
clang++ -std=c++11 test.cc -o test.
我只想模仿与 C++ 中的“交换习语”相同的行为,以使用“使用指令”来启用 ADL。但是下面的代码我哪里错了?预期的呼叫优先级应该是:N1::foo> N2::foo> ::foo,对吗?
namespace N1 {
struct S {};
void foo(S s) {
std::cout << "called N1::foo.";
}
}
namespace N2 {
void foo(N1::S s) {
std::cout << "called N2::foo.";
}
}
void foo(N1::S s) {
std::cout << "called foo.";
}
int main() {
using N2::foo;
foo(N1::S{});
}
Run Code Online (Sandbox Code Playgroud)
错误信息:
test.cc:54:3: error: call to 'foo' is ambiguous
foo(N1::S{});
^~~
test.cc:40:8: note: candidate function
void foo(S …Run Code Online (Sandbox Code Playgroud) 那么,Rust 中的“*const()”究竟是什么?似乎我可以在 Rust 中为这种类型“作为”一些原始值(整数值、函数),如下所示:
let foo = 1;
let pointer = foo as *const (); // this works.
Run Code Online (Sandbox Code Playgroud)
但是对于浮点数等,编译器不允许我们做上述的强制转换,那么 Rust 中的“*const()”是什么?它与void*C/C++ 中的类似吗?如果是这样,为什么它不支持指向浮点数?
顺便说一句,在参考中添加了当前使用此模式的情况:https : //doc.rust-lang.org/std/mem/fn.transmute.html。
fn foo() -> i32 {
0
}
let pointer = foo as *const (); // here it is!!!
let function = unsafe {
std::mem::transmute::<*const (), fn() -> i32>(pointer)
};
assert_eq!(function(), 0);
Run Code Online (Sandbox Code Playgroud) 我知道 Rust 应用程序初始化条目是由rustc. 我检查了compiler/rustc_codegen_ssa/src/base.rs 中的代码,它的一部分如下所示。
fn create_entry_fn<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
cx: &'a Bx::CodegenCx,
rust_main: Bx::Value,
rust_main_def_id: DefId,
use_start_lang_item: bool,
) -> Bx::Function {
// The entry function is either `int main(void)` or `int main(int argc, char **argv)`,
// depending on whether the target needs `argc` and `argv` to be passed in.
let llfty = if cx.sess().target.main_needs_argc_argv {
cx.type_func(&[cx.type_int(), cx.type_ptr_to(cx.type_i8p())], cx.type_int())
} else {
cx.type_func(&[], cx.type_int())
};
Run Code Online (Sandbox Code Playgroud)
而且我在同一个文件中发现的东西真的很有趣,就像我下面展示的那样,从评论中,我们可以了解到 Rust 正在这个地方收集输入的 argc 和 argv,这两个参数都将在lang_start稍后传递到函数中如果我理解正确。
/// …Run Code Online (Sandbox Code Playgroud) 为什么那些“加载”和“存储”操作符需要一个“对齐”属性,它是如何与内存对齐一起工作的?
顺便说一句,为什么我们需要这个操作符,因为底层系统会自动为我们做内存对齐?
如题,为什么main函数中的模板实例化出错了?我使用带有标志“-std=c++2a”的 Clang++。我在这里以错误的方式使用了什么吗?
template<int, int>
void f(int) { std::cout << "int"; };
template<class T>
void g() { // dependent-name.
f<0, T()>(0);
}
int main() {
g<int>(); // wrong here, why?
}
Run Code Online (Sandbox Code Playgroud)
来自 Clang 的错误消息:
test.cc:41:3: error: no matching function for call to 'f'
f<0, T()>(0);
^~~~~~~~~
test.cc:48:3: note: in instantiation of function template specialization 'g<int>' requested here
g<int>(); // "int";
^
test.cc:35:6: note: candidate template ignored: invalid explicitly-specified argument for 2nd
template parameter
void f(int) { std::cout << "int"; };
^ …Run Code Online (Sandbox Code Playgroud) 对于已注释掉的行,请参考下面的代码。它不能被 Rust 编译器编译,这意味着我们需要为*const i32Rust 中的原始指针显式指定常量。但是对于对其指针对象不可变的引用,我们不需要像使用原始指针那样显式指定常量。那么,为什么 Rust 不使用更对称的方式来表达引用和原始指针的相同含义,因为引用实际上是引擎盖下的指针?
fn main() {
let x1: &i32;
let x2: &mut i32;
// let p1: *i32; // This line doesn't compile!!!
let p1: *const i32; // we need to specify the constness explicitly.
let p2: *mut i32;
}
Run Code Online (Sandbox Code Playgroud) 假设我们有以下代码,我在其中定义了一个名为closure. 在这个闭包中,我想x通过不可变引用 ( &T)来使用外部,同时,y通过获取所有权来使用。我怎样才能做到这一点?如果我使用move,闭包中使用的所有外部变量都将移动到闭包中。而且这里的外部变量y是可复制的。
let x: i32 = 1;
let y: i32 = 2;
let closure = || {
println!("{}", x); // make sure x is used by &T.
// println!("{}", y); // how can I use y by taking its ownership?
};
closure();
Run Code Online (Sandbox Code Playgroud) 如题。
例如,假设我们有一个int8_t值“-10”,我想在我的程序中动态检查(运行时值)是否-10可以在uint32_t变量之后安全地保存这个确切的整数值std::trunc。在这种情况下,由于这是一个负值,所以它不能被无符号类型保存。我怎样才能在 C++ 代码中做到这一点?因为如果我使用正常的比较方式,隐式转换会破坏如下所示的类型信息。有没有其他简单的方法可以做到这一点?
int8_t v = -10;
if (v <= std::numeric_limits<uint32_t>::max() &&
v >= std::numeric_limits<uint32_t>::min()) {
// It will be true here.
}
Run Code Online (Sandbox Code Playgroud)
我想找到一种健全的方法来检查目标类型的可用值范围是否可以完全覆盖源类型的所有可用值。意思是显式转换后,结果值应该与原始值完全相同。
我从使用 Clang++ 在不同 C++ 版本下运行的相同代码片段得到了不同的结果。当我用 C++17 编译代码时,编译器似乎自动调用了 RVO/NRVO,好奇这是一个错误还是不同的功能?
Apple clang 版本 11.0.0 (clang-1100.0.33.17)
使用以下命令在C++11下运行:
clang++ test.cc -fno-elide-constructors -std=c++11 -o test
结果:
Move Constructor
Move Constructor
100
Run Code Online (Sandbox Code Playgroud)
使用以下命令在C++17下运行:
clang++ test.cc -fno-elide-constructors -std=c++17 -o test
结果:
100
Run Code Online (Sandbox Code Playgroud)
代码(test.cc):
struct A {
A() = default;
A(int v) : p(new int(v)) {}
~A() { delete p; }
A(const A&) = delete;
A& operator=(const A&) = delete;
A(A&& rhs) noexcept : p(rhs.p) {
std::cout << "Move Constructor" << std::endl;
rhs.p = …Run Code Online (Sandbox Code Playgroud) 我从 NASM 的文档中看到了以下规则:
在进行调用之前,堆栈指针 %rsp 必须与 16 字节边界对齐。很好,但是进行调用的过程会将返回地址(8 个字节)压入堆栈,因此当函数获得控制权时,%rsp 未对齐。你必须自己创造额外的空间,通过推动某些东西或从 %rsp 中减去 8。
我有一段 NASM 汇编代码,如下所示:
在我调用“_start”中的函数“inc”之前,%rsp 应该位于 8 字节的边界,这违反了 NASM 文档中描述的规则。但实际上,一切都在进行中。那么,我如何理解这一点呢?
我是在 Ubuntu 20.04 LTS (x86_64) 下构建的。
global _start
section .data
init:
db 0x2
section .rodata
codes:
db '0123456789abcdef'
section .text
inc:
mov rax, [rsp+8] ; read param from the stack;
add rax, 0x1
ret
print:
lea rsi, [codes + rax]
mov rax, 1
mov rdi, 1
mov rdx, 1
syscall
ret
_start:
; enable AC check;
pushf
or …Run Code Online (Sandbox Code Playgroud)