小编Nik*_*lai的帖子

在一个结构中,使用一个数组字段访问另一个数组字段是否合法?

例如,请考虑以下结构:

struct S {
  int a[4];
  int b[4];
} s;
Run Code Online (Sandbox Code Playgroud)

写作s.a[6]并期望它等于是合法的s.b[2]吗?就个人而言,我觉得它必须是C++中的UB,而我不确定C.但是,我没有找到任何与C和C++语言相关的内容.


更新

有几个答案建议确保字段之间没有填充以使代码可靠地工作的方法.我想强调的是,如果这样的代码是UB,那么填充缺失是不够的.如果它是UB,那么编译器可以自由地假设访问S.a[i]S.b[j]不重叠,并且编译器可以自由地重新排序这样的存储器访问.例如,

    int x = s.b[2];
    s.a[6] = 2;
    return x;
Run Code Online (Sandbox Code Playgroud)

可以转化为

    s.a[6] = 2;
    int x = s.b[2];
    return x;
Run Code Online (Sandbox Code Playgroud)

总是回来2.

c c++ arrays struct

51
推荐指数
5
解决办法
4449
查看次数

如何在Rust中为特定集合类型(列表/集合/地图)创建一个空的迭代器?

我想编写一个返回集合迭代器(例如 LinkedList)的方法。但是在某些情况下,没有合适的集合可以返回迭代器。在这种情况下,我想返回一个“空”迭代器,该迭代器不对任何元素进行迭代。但是,我找不到任何相关的功能构建linked_list::Iter的文档

考虑以下示例:

use std::collections::HashMap;
use std::collections::LinkedList;
use std::collections::linked_list;

pub struct Graph {
    nodes: HashMap<usize, LinkedList<usize>>,
}

impl Graph {
    pub fn adjacent_nodes(&self, node: usize) -> linked_list::Iter<usize> {
        match self.nodes.get(&node) {
            Some(x) => x.iter(),
            _ => linked_list::Iter::<usize>::new()
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我想从该adjacent_nodes 方法的相邻节点上返回一个迭代器。但是,当要求一个不存在的节点的邻居时,该方法显然应该返回一无所有的迭代器。但是我怎么创建它呢?我提供的代码实际上无法编译:

src/graph.rs:13:18: 13:49 error: no associated item named `new` found for type
        `collections::linked_list::Iter<'_, usize>` in the current scope
src/graph.rs:13             _ => linked_list::Iter::<usize>::new()
                                 ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Run Code Online (Sandbox Code Playgroud)

我猜想,我可以解决此问题,boxed::Box但由于我试图避免不必要的堆分配,显然这不是次优的解决方案。

所以,我的问题是:在Rust中是否可以创建特定类型的迭代器?

iterator rust

7
推荐指数
1
解决办法
1033
查看次数

为内联汇编创建常量池的正确方法是什么?

问题是在C函数内部我有一个内联汇编.就像是

  ldr r7, =0xdeadbeef
  svc 0
Run Code Online (Sandbox Code Playgroud)

如果没有显式创建文字池(这是这种情况),汇编程序会在翻译单元的末尾创建一个文字池.通常这很好,但是如果翻译单元真的很大,那么这不起作用,因为文字池离ldr指令太远了.

所以,我想知道处理这个问题的最佳方法是什么.最明显的方法是在内联汇编中手动创建文字池:

  ldr r7, =0xdeadbeef
  svc 0
  b 1f
  .ltorg
1:
Run Code Online (Sandbox Code Playgroud)

要么

  ldr r7, 1f
  svc 0
  b 2f
1:
  .word 0xdeadbeef
2:
Run Code Online (Sandbox Code Playgroud)

不幸的是,由于冗余分支指令,这导致了次优代码.我不希望汇编器足够聪明,为函数内部的常量池找到合适的位置.我想要做的是在函数的末尾创建一个常量池.有没有办法告诉编译器(gcc)在函数末尾创建一个文字池?

PS我最终使用了movw/movt对而不是常量池.虽然,首先,movw/movt解决方案的可移植性略低于文字池,其次,我只是想知道是否可以可靠而有效地在内联汇编中使用常量池.


更新: 那么,处理问题的最佳方法是什么?

要强制工具链在函数之后创建一个常量池,可以将函数放在单独的代码部分中.它的工作原理是因为在翻译单元结束时汇编程序为每个部分生成单独的常量池.

实际上,最好的方法是避免将常量加载到内联汇编中的寄存器中.让编译器这样做会更好.在我的情况下,我最终写了一个类似的代码

register int var asm("r7") = 0xdeadbeef;
asm volatile("svc 0\n" :: "r" (var));
Run Code Online (Sandbox Code Playgroud)

c gcc arm inline-assembly

6
推荐指数
1
解决办法
804
查看次数

什么是 PDE 缓存?

我有以下基于 ARM 的 SoC 规格:

  • L1 数据缓存 = 32 KB, 64 B/line, 2-WAY, LRU
  • L2 缓存 = 1 MB,64 B/线,16 路
  • L1 数据 TLB(用于加载):32 个条目,完全关联
  • L2 数据 TLB:512 个条目,4 路
  • PDE 缓存:16 个条目(每 1 MB 虚拟空间一个条目)

我想知道什么是 PDE 缓存?我想它类似于 TLB,但我不确定。

回答
似乎 PDE(页面目录条目)是中间表遍历缓存,它确实可以与 TLB 分开实现。

Cortex-A15 MPCore 处理器实现了专用缓存,将中间级别的转换表条目存储为表遍历的一部分。

arm computer-architecture tlb cpu-cache mmu

4
推荐指数
3
解决办法
1330
查看次数

标签 统计

arm ×2

c ×2

arrays ×1

c++ ×1

computer-architecture ×1

cpu-cache ×1

gcc ×1

inline-assembly ×1

iterator ×1

mmu ×1

rust ×1

struct ×1

tlb ×1