Open
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
保留 inline 且能成功編譯的修改說明
一、問題來源
專案中多個 header(
vector.h、bitvector.h、boolformula.h、cdnfformula.h)把函式宣告成static inline或inline,但只有宣告、沒有定義;實際定義在對應的.c裡,且用inline。在 C99 下:
inline、沒有extern的定義不會產生可供連結的外部符號。.c只看到 header 的宣告,編譯時無法 inline,連結時又找不到符號 → undefined reference。此外,header 被 C 與 C++ 共用(例如 cpp_examples);在 C++ 中
malloc回傳void*,不能隱式轉成其他指標型別,需顯式轉型。二、目標
.c裡都能 inline 這些小函式,而不是只在本檔或依賴 LTO。三、作法總覽
採用 「在 header 裡用
static inline並提供完整定義」 的方式,讓每個 include 該 header 的編譯單元都有一份定義,編譯器可以選擇 inline,且不會產生連結符號問題。1. vector(vector.h / vector.c)
#include <assert.h>。vector_length、vector_get、vector_set、vector_add改為static inline且在本檔內寫完整定義(含函式本體)。vector_new、vector_free、vector_resize與內部 helper。效果:任何 include
vector.h的 .c(含 cdnfformula、boolformula、cdnf、oracle 等)都能在編譯時 inline 這四個 accessor。2. bitvector(bitvector.h / bitvector.c)
#include <assert.h>。BITVECTOR_BITS_IN_INT、bitvector_array_idx()、bitvector_bit_pos()(避免與 .c 內部的 macro 衝突)。bitvector_length、bitvector_set、bitvector_get改為static inline且在本檔內寫完整定義。BITS_IN_INT/get_array_idx/get_bit_pos。效果:任何 include
bitvector.h的 .c 都能 inline 這三個 accessor。3. boolformula(boolformula.h / boolformula.c)
#include "type.h","vector.h",<assert.h>,<stdlib.h>,<stdio.h>,<stdbool.h>(C 用)。static inline+ 完整定義,包括:boolformula_lit_from_var,boolformula_var_from_lit,boolformula_lit_complement,boolformula_positive_litboolformula_disjunction_unit/new,boolformula_conjunction_unit/new,boolformula_literal_new,boolformula_add,boolformula_set,boolformula_free,boolformula_negboolformula_copy(須放在boolformula_to_cnf之前,避免未宣告就使用)add_clauses_to_boolformula(僅被boolformula_to_cnf使用,一併放進 header)boolformula_to_cnf,boolformula_get_type,boolformula_get_length,boolformula_get_subformula,boolformula_get_valuemalloc(sizeof(boolformula_t))改為(boolformula_t*)malloc(sizeof(boolformula_t)),以便 C++ 編譯通過。boolformula_print,boolformula_num_of_var。NOT_A_LITERAL、boolformula_print、boolformula_num_of_var。效果:所有 include
boolformula.h的 .c/.cc 都能 inline 上述函式,且 C 與 C++ 皆可編譯。4. cdnfformula(cdnfformula.h / cdnfformula.c)
#include "type.h","vector.h","bitvector.h","boolformula.h",<assert.h>,<stdlib.h>。static inline+ 完整定義,包括:cdnfformula_monomial_unit,cdnfformula_monomial_add,cdnfformula_monomial_M_DNFcdnfformula_disjunction_unit/new/add/free,cdnfformula_conjunction_unit/new/add,cdnfformula_freemonomial_to_boolformula,dnf_to_boolformula,cdnfformula_to_boolformulacdnfformula_print,cdnfformula_eval_M_DNF。cdnfformula_conjunction_new回傳型別為conjunction *(非disjunction *)。cdnfformula_monomial_to_string,cdnfformula_disjunction_to_string,cdnfformula_print,cdnfformula_eval_monomial,cdnfformula_eval_M_DNF。效果:所有 include
cdnfformula.h的 .c/.cc 都能 inline 上述函式。5. c_examples / cpp_examples
satisfible若需被連結,改為extern inline(或改為一般函式並在 header 宣告),讓該 .c 產出一個外部符號,連結時可解析。malloc的顯式轉型,使 cpp_examples 能成功編譯。四、為何這樣能「保留所有 inline」且能編譯
static inlinemalloc結果做顯式轉型(boolformula_t*)malloc(...),C 與 C++ 皆可編譯。boolformula_copy、add_clauses_to_boolformula)在呼叫者(如boolformula_to_cnf)之前定義,避免隱式宣告。五、建置結果
libcdnfp.a。learn(需satisfible有正確宣告/定義)。整體而言:「在 header 內用
static inline提供完整定義 + C/C++ 相容的 malloc 轉型」,既能保留所有 inline 的優化機會,又能讓專案在 C 與 C++ 下都成功編譯、連結。