va_arg巨集,是頭文件 stdarg.h 中定義的,獲取可變參數的當前參數。 #define va_arg(list, mode) ((mode*)(list+=sizeof(mode)))[-1] 這個-1操作,是返回當前指針前一個值。如果你熟悉c++中記憶體模型就應該明白。array 在記憶體棧或 ...
va_arg巨集,是頭文件 stdarg.h 中定義的,獲取可變參數的當前參數。
#define va_arg(list, mode) ((mode*)(list+=sizeof(mode)))[-1]
這個-1操作,是返回當前指針前一個值。如果你熟悉c++中記憶體模型就應該明白。array 在記憶體棧或者堆中是連續的一段空間。
如果我們對一個數組 int a[10]進行a[-1]操作,那麼就可能出現錯誤,因為我們這時候出現了不可控的指針操作,返回的值是不可預料的。
為了能夠構造 a[-1]的操作,我們進行如下構造,並比較了記憶體地址的值(va_list.c):
#include <stdio.h> int main(){ int a[]={1, 2, 3, 4, 5, 6, 7, 8, 9}; int *p = &a[1]; printf("%d %d %d\n", p[-1], a[0], a[2]); printf("paddr=%d, aaddr=%d, addr2=%d\n", &p[-1], &a[0], a+0); return 0; }
編譯:
cc va_list.c -o listd
輸出結果:
➜ va_list ./listd 1 1 3 paddr=1430784032, aaddr=1430784032, addr2=1430784032
至此,-1操作的原理大概已經清晰。如果對編譯原理理解稍微深刻的話,可能能進一步理解:我們實際上的這些操作都會被編譯器解釋為相同符號。
參考鏈接:https://www.cnblogs.com/bettercoder/p/3488299.html
保持更新,轉載請註明出處。