我看到如下结构:
#ifdef FOO || defined BAR
...
#endif
Run Code Online (Sandbox Code Playgroud)
和编译器的投诉"警告:#ifdef指令末尾的额外令牌",显然它应该是:
#if defined FOO || defined BAR
...
#endif
Run Code Online (Sandbox Code Playgroud)
标准是否明确说明了?你能指出相关部分吗?
考虑下面的代码:
#ifdef AAA && (defined BBB)
...
#endif
Run Code Online (Sandbox Code Playgroud)
gcc-4.5.2在这条线上抱怨:
#ifdef指令末尾的额外令牌.
它是非法的结合ifdef和defined?
谢谢!
#define MAX_SIZE 8
enum my_enum
{
VAL1 = 0;
VAL2,
VAL3,
VAL4,
VAL_MAX
};
struct my_struct
{
enum my_enum e;
int w[MAX_SIZE];
};
Run Code Online (Sandbox Code Playgroud)
这种结构中的布局是否会导致目标平台上的对齐问题?我理解它很大程度上取决于一个平台,但通常允许C编译器对结构进行填充,例如在32位机器上,其中'int'是32位长:
struct my_struct
{
int w[MAX_SIZE];
}
Run Code Online (Sandbox Code Playgroud)
是对齐的(就像我所理解的那样)因此编译器可能不会对其布局做任何其他事情,但在结构中添加"enum my_enum"可以在这样的机器上无法对齐地获得结构.我应该做些什么来避免这种情况吗?我应该完全避免它吗?
非常感谢澄清!
标记
我已阅读https://en.wikipedia.org/wiki/YANG但仍然无法理解 的实际用途YANG及其提供的好处。据我了解,它现在不仅像最初设计的那样由 NETCONF 使用。YANG不是普通意义上的语言,例如C,python我们所写的任何内容都YANG不会被编译或翻译;据我了解,它被用作更高级别的库或应用程序的参考模型。那么问题是高层代码如何理解呢YANG?
在阅读man bpf了一些其他文档来源后,我的印象是a map只能由用户进程创建.然而,以下小程序似乎神奇地创建了bpf地图:
struct bpf_map_def SEC("maps") my_map = {
.type = BPF_MAP_TYPE_ARRAY,
.key_size = sizeof(u32),
.value_size = sizeof(long),
.max_entries = 10,
};
SEC("sockops")
int my_prog(struct bpf_sock_ops *skops)
{
u32 key = 1;
long *value;
...
value = bpf_map_lookup_elem(&my_map, &key);
...
return 1;
}
Run Code Online (Sandbox Code Playgroud)
所以我用内核加载程序,tools/bpf/bpftool并验证程序是否已加载:
$ bpftool prog show
1: sock_ops name my_prog tag f3a3583cdd82ae8d
loaded_at Jan 02/18:46 uid 0
xlated 728B not jited memlock 4096B
$ bpftool map show
1: array …Run Code Online (Sandbox Code Playgroud) 这是谁在 BPF 中创建地图的后续行动,因为我的新问题与该线程没有直接关系。
所以,在我看来,必须有一个点在那里创建了一个BPF地图,无论它是一个BPF程序或用户程序加载BPF等。
BPF 程序必须在编译时知道它要使用的映射类型,所以我们需要:
struct bpf_map_def SEC("maps") my_map = {
...
};
Run Code Online (Sandbox Code Playgroud)
因此,这意味着,例如bpftool,用户程序将启动在 bpf ELF 部分中找到的映射的创建,如谁在 BPF线程中创建映射所示。
另一方面,用户应用程序需要在地图中添加/删除条目。要做到这一点,它必须知道 mapID以便bpf_map_get_fd_by_id()从 from获得 get map 的 fd libbpf。之后我们就可以享受bpf_map_update_elem()和类似的API了。
另一方面,如果我们在 BPF 程序中声明了一个映射部分并且确实使用了映射 API,那么映射将被保留在内核中并被分配 ID。
因此,在这种情况下,我们将有两个具有两个不同 ID 的映射:一个作为bpf_prog_load()from的结果创建bpftool,另一个来自用户应用程序的bpf_create_map()(假设应用程序继续运行,例如更新映射,并且不返回到 shell )。
一定有办法绕过这种歧义吗?
我正在查看ebpf验证器代码,但无法理解以下宏:
#define offsetof(TYPE, MEMBER) ((size_t)&((TYPE *)0)->MEMBER)
#define offsetofend(TYPE, MEMBER) \
(offsetof(TYPE, MEMBER) + sizeof(((TYPE *)0)->MEMBER))
<...>
#define bpf_ctx_range(TYPE, MEMBER) \
offsetof(TYPE, MEMBER) ... offsetofend(TYPE, MEMBER) - 1
#define bpf_ctx_range_till(TYPE, MEMBER1, MEMBER2) \
offsetof(TYPE, MEMBER1) ... offsetofend(TYPE, MEMBER2) - 1
Run Code Online (Sandbox Code Playgroud)
我理解offsetof宏offsetofend,但是什么...意思呢?
谢谢。
C 标准怎么说:
uint32_t a = 0x11223344;
uint16_t b = a;
Run Code Online (Sandbox Code Playgroud)
打印时,我得到 0x3344,这是有道理的;所以这必须是合法和正确的行为?
考虑以下片段:
void my_func(int a, void *b);
...
struct my_struct s = { };
my_func(10, (void *)&s);
Run Code Online (Sandbox Code Playgroud)
(void *)传递&s给函数时是否需要类型转换?
class A:
def __init__(self):
self.name = None
self.a = 10
self.b = 20
self.c = 30
def func1(self, param1, param2):
def inner_func1(self, param1, param2):
print(self, self.a, self.b)
inner_func1(self, param1, param2)
a = A()
print(a)
a.func1(1,2)
Run Code Online (Sandbox Code Playgroud)
我的第一个问题——将self参数传递给类方法的嵌套函数是否合法?我在 python-3.5.2 上运行此代码没有问题,并且都print()显示 A 类实例的相同地址。然而蟒蛇-3.6抱怨上线print(self, self.a, self.b)是self没有成员a。
同样有趣的是 PyCharm IDE 没有突出显示self这一行,而是说它“超出了外部范围”。
我到底做错了什么?
c ×6
bpf ×3
linux-kernel ×3
ebpf ×2
types ×2
casting ×1
integer ×1
macros ×1
model ×1
pointers ×1
python ×1
python-3.x ×1
python-class ×1
schema ×1