2012-03-04 31 views
4

用C語言編程,有沒有什麼技術可以用來避免(或者至少是最小化)將void *錯誤地轉換爲錯誤的指針類型?我正在研究一個解析幾種不同類型的CSV數據文件的程序,並將這些字段存儲到特定的數據結構中進行處理。例如,其中一個數據文件的記錄存儲在散列表中;來自另一個文件的數據存儲在有向圖中。如何避免錯誤地將void *轉換爲錯誤的類型?

我想創建一個主解析函數,從文件中讀取字段記錄,並將每個記錄傳遞給一個函數,該函數將字段標記並將其存儲在適當的數據類型中。我不想爲每個文件類型創建單獨的解析/標記函數,而是想創建一個通用函數來執行此操作。在我的設計中,調用函數將傳遞字段記錄,指向適用於數據文件的標記器的函數指針,以及指向適用於數據文件的目標數據結構節點的void *。

我想知道的是,是否有任何方法可以確保用戶不會錯誤地使用不匹配的標記器/數據結構調用解析函數。 (通過使用指向void的指針,編譯器肯定是無能爲力的。)或者,如果沒有這樣的技術,是否有任何有效的異常處理方法來捕獲此錯誤並防止出現重大問題(例如,sigfaults)?

我希望代碼儘可能便攜。

有什麼想法?我沒有結婚這個算法,如果有人有一個更好的主意,我願意接受。

+2

用類型字段前綴你的結構並在轉換後檢查它? – 2012-03-04 00:23:51

+2

我很肯定答案是'不';當你使用void *時,你會選擇自己跟蹤數據類型。 – Kevin 2012-03-04 00:23:52

+2

您可以創建'struct {unsigned short char type; void * data;}' – Vyktor 2012-03-04 00:24:16

回答

5

一種可能性是創建一組抽象掉了類型安全問題非常薄的包裝函數:

void foo_generic(FieldRecords *records, Parser *parser, void *dest); 

... 

void foo_A(FieldRecords *records, A *dest) { foo_generic(records, &parse_A, dest); } 
void foo_B(FieldRecords *records, B *dest) { foo_generic(records, &parse_B, dest); } 
void foo_C(FieldRecords *records, C *dest) { foo_generic(records, &parse_C, dest); } 

現在所有錯別字的潛力被限制到一個位置,其中的錯誤應該更容易由於對稱性而找到。

如果你感覺特別淘氣,你可以使用宏來簡化這些包裝函數生成:

#define FOO(T) void foo_##T(FieldRecords *records, T *dest) { \ 
        foo_generic(records, &parse_##T, dest); \ 
       } 

FOO(A) 
FOO(B) 
FOO(C) 

這個錯別字的概率最小化,但會增加混淆調試器/ IDE的機會!

+0

謝謝,這是一個很好的解決方案。 – THV 2012-03-04 16:31:47

相關問題