告知clang内联汇编读取特定的内存区域

GCC(我可以方便地测试的所有版本)可以告诉内联汇编语句读取一个特定的内存区域(表示为指针p和大小为n ),这个结构非常难以理解:

 asm ("..." : : "m" (*(struct { char x[n]; } *)p)); 

但是,这在clang中不起作用(3. [45]),你得到一个很难的错误:

  error: fields must have a constant size: 'variable length array in structure' extension will never be supported asm ("..." : : "m" (*(struct {char x[n];} *)p)); ^ 

是否(理想情况下)是一个不同的构造,它将在两个编译器中产生相同的效果,或者(不这样)一个不同的构造,只会在clang中产生相同的效果?

请注意,在我关心的情况下,我没有插入实际的assembly说明; 构造的要点是指示编译器不要删除明显死的memset 。 因此,“不同构造”完全不能完全涉及内联组装。 但是,请建议读取任意内存或生成其他代码的构造,只有在没有其他选择的情况下。 另外,不要建议memset_sexplicit_bzero或类似的; 这是尝试在不必破解编译器的情况下实现这些函数的回退。

随后是全面的演示程序 –

 #include  extern void foo(const char *a, const char *b, const char *c, char *d); void bar(const char *x, char *y, size_t n) { char w[16]; char v[n]; memset(w, 0x11, n); memset(v, 0x22, n); foo(w, v, x, y); memset(w, 0, 16); memset(v, 0, n); asm ("" : : "m" (*(struct {char _[n];} *)v)); } 

– 由gcc 5.0编译-O2 -S ,x86-64,CFI goo elided –

 bar: pushq %rbp leaq 15(%rdx), %rax movq %rsp, %rbp pushq %r14 andq $-16, %rax movq %rsi, %r14 pushq %r13 movl $17, %esi movq %rdi, %r13 pushq %r12 leaq -48(%rbp), %rdi pushq %rbx movq %rdx, %rbx subq $16, %rsp subq %rax, %rsp call memset movq %rbx, %rdx movq %rsp, %rdi movl $34, %esi call memset movq %r14, %rcx movq %r13, %rdx movq %rsp, %rsi leaq -48(%rbp), %rdi call foo movq %rbx, %rdx xorl %esi, %esi movq %rsp, %rdi call memset leaq -32(%rbp), %rsp popq %rbx popq %r12 popq %r13 popq %r14 popq %rbp ret 

– 目标是从clang中获得相同数量的块内存填充。 两个是错的,但四个也是错的。