C语言编程技巧/C Programming Tips
目录
1 说明
本文不介绍基本C语言编程,只记录实际代码中用到的各种编程技巧,这些技巧一般是GCC 编译器强相关的,
2 返回结构体
使用型别强制转换与打括号组合,返回结构体类别:
#include <stdio.h> struct bucket { int array[128]; }; struct slot { int x; struct bucket *bucket; }; static inline struct slot __to_slot(unsigned long v) { return (struct slot){v & 3, (struct bucket *)(v & ~3)}; } int main() { struct slot sl; sl = __to_slot(0x1234567890abcdef); printf("bucket=%p, x=%x\n", sl.bucket, sl.x); return 0; }
3 内联汇编
3.1 基本格式
3.1.1 语法
asm("assembly code");
- 指令在引号之间
- 多行汇编语言之间要加上换行"\n",一般也加上"\t"进行适度缩进
- 添加\(volatile\)禁止编译器优化inline汇编
- ANSI C对\(asm\)有其他定义,可替换为\(__asm__\)关键字替换
3.1.2 示例
#include <stdio.h> int a = 10, b = 20, r = 0; int main() { asm volatile("movl a, %eax\n\t" "addl b, %eax\n\t" "movl %eax, r\n\t"); printf("%d + %d = %d\n", a, b, r); return 0; }
3.2 扩展格式
3.2.1 语法
asm("assembly code" : output locations : input operands : changed registers);
- assembly code
- 与基本格式的assembly code格式相同,
- output locations
- inline汇编代码输出
3.3 cpu ticks rdstc
3.3.1 inline function
#include <stdio.h> #include <time.h> #include <unistd.h> static __always_inline unsigned long rdtsc_ordered(void) { unsigned long low, high; asm volatile("mfence\n\tlfence\n\t" ::: "memory"); asm volatile("rdtsc" : "=a" (low), "=d" (high)); return low | (high << 32); } int main() { unsigned long start, end; start = rdtsc_ordered(); usleep(1000); end = rdtsc_ordered(); printf("elapsed=%lu [start=%lu end=%lu]\n", end - start, start, end); return 0; }
3.3.2 gcc extend macro
#include <stdio.h> #include <time.h> #include <unistd.h> #define rdtsc_ordered() ({ \ unsigned long low, high; \ asm volatile("mfence\n\tlfence\n\t" ::: "memory"); \ asm volatile("rdtsc" : "=a" (low), "=d" (high)); \ low | (high << 32); }) int main() { unsigned long start, end; start = rdtsc_ordered(); usleep(1000); end = rdtsc_ordered(); printf("elapsed=%lu [start=%lu end=%lu]\n", end - start, start, end); return 0; }
4 Reference Materials
- LWN A guide to inline assembly code in GCC
- https://lwn.net/Articles/685739/