[英]What is the logic behind defining macros inside a struct?
正如標題中所顯示的,我正在質疑在結構中定義宏的原因。 我經常在網絡編程中看到這種方法,例如以下片段:
struct sniff_tcp {
u_short th_sport; /* source port */
u_short th_dport; /* destination port */
tcp_seq th_seq; /* sequence number */
tcp_seq th_ack; /* acknowledgement number */
u_char th_offx2; /* data offset, rsvd */
#define TH_OFF(th) (((th)->th_offx2 & 0xf0) >> 4)
u_char th_flags;
#define TH_FIN 0x01
#define TH_SYN 0x02
#define TH_RST 0x04
#define TH_PUSH 0x08
#define TH_ACK 0x10
#define TH_URG 0x20
#define TH_ECE 0x40
#define TH_CWR 0x80
#define TH_FLAGS (TH_FIN|TH_SYN|TH_RST|TH_ACK|TH_URG|TH_ECE|TH_CWR)
u_short th_win; /* window */
u_short th_sum; /* checksum */
u_short th_urp; /* urgent pointer */
};
此示例來自tcpdump網站中的sniffex.c代碼。
這是為了增強可讀性和使代碼更清晰。
好吧,定義的常量與其中一個字段的可能值相關。
因此,作者決定改進代碼局部性,並使API用戶避免在圈內運行。 似乎合乎邏輯。
否則,預處理器完全獨立於代碼。 您甚至可以在表達式中放置一個定義。
我們不得不懷疑它正試圖向我們傳達這些宏只與這個結構中的數據一起使用,但這是一種很糟糕且復雜的方式來表示它。
在C ++中,最好使用嵌套的枚舉和內聯函數來實現這一點,但由於代碼是C,宏可能是最好的選擇。
在我看來,它降低了可讀性,我更願意看到結構外部的宏,注釋表明它們應該在何處以及如何使用。 這樣就無法猜測宏究竟是為了什么而且結構定義沒有任何缺陷。
一種典型用法如下所示
假設您的第一個版本的foo有點如下所示。
struct foo1 {
int x;`enter code here`
...
};
明天你會嘗試通過以下方式增強結構
struct foo2 {
union {
int x;
int y;
} u;
#define x u.x
#define y u.y
};
上面做的聲明不會破壞你使用foo_var.x的地方的編譯,因為結構的新定義foo_var.x仍然有效,只不過是foo_var.ux
例如:用法:
struct foo {
union {
int x;
int y;
} u;
#define x u.x
#define y u.y
};
int main()
{
struct foo f;
f.x = 1;
f.y = 2;
}
我認為,這不是“最佳實踐”,應該在結構附近保留定義(對於值),而不是在結構內部。
(更好的是enum和typedef常量,因此如果沒有正確輸入,編譯器可能會發出警告)。
TH_OFF()宏是另一種情況,它“隱藏”另一個元素,所以也許它可以放在這個位置(帶有適當的注釋)
作者的意圖似乎是屬於一起的東西應該放在一起。 因此,標志宏應位於標志下方。 使用相同的邏輯,宏定義與結構聲明無關,因此宏不屬於那里。 將它們放在結構上方或下方沒有任何問題。
我想知道如果該標志是一個帶有32個標志宏的u_long和一些更多的其他默認組合宏,那么作者是否會保持一致並做同樣的事情?
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.