簡體   English   中英

與鏈接靜態庫相比,為什么從源構建時gcc會產生不同的結果?

[英]Why does gcc produce a different result when bulding from source compared to linking a static library?

我有一個C ++ 14文件my.cpp ,並且在其中嘗試使用一個名為open62541的C99庫。 對於后者,完整源代碼open62541.c/.h和庫libopen62541.a存在。 my.cpp ,其中包括open62541.h ,我使用的是C ++特定代碼(例如iostream),因此從技術上講,我正在混合C和C ++。

我可以my.cpp通過引用成功編譯libopen62541.a

gcc -x c++ -std=c++14 -Wall my.cpp -l:libopen62541.a -lstdc++ -o out

這不會輸出任何警告,並創建一個可執行文件out

但是,如果我嘗試僅使用源代碼進行編譯:

gcc -x c++ -std=c++14 -Wall my.cpp open62541.c -lstdc++ -o out

我收到很多ISO C ++警告(例如,“ ISO C ++禁止將字符串常量轉換為'char '*”)和源自open62541.c一些“ 跳轉到標簽 ”錯誤,導致編譯失敗。

我可以使用-fpermissive開關使編譯成功:

gcc -x c++ -std=c++14 -Wall my.cpp open62541.c -lstdc++ -fpermissive -o out

仍然會輸出很多警告,但會成功創建可執行文件。 但是,我不確定這樣做是否是個好主意。

也許值得一提的是open62541.h在一開始就考慮使用C ++:

#ifdef __cplusplus
extern "C" {
#endif
  1. 假設與open62541庫代碼捆綁在一起的.a庫是從同一源構建的,為什么前兩種方法在生成警告和錯誤方面不一致? 為什么一個起作用而另一個不起作用?

  2. 鏈接.a與引用.c的一種方法是否應該優先於另一種方法? 我的印象是它們應該等效,但顯然不是。

  3. 在這種情況下,使用-fpermissive是否更多是可以掩蓋潛在問題的技巧,因此應避免使用?

您看到的錯誤(和警告)是C ++編譯器在編譯C代碼時輸出的編譯錯誤(和警告)。

例如,在C中, "literal"類型為char[]而在C ++中,其類型為const char[]

您會從open62541.c得到一個C ++編譯器libopen62541.a open62541.c ,您將看到相同的錯誤(警告)。 但是C編譯器可能會滿意(取決於該C源文件的狀態)。

另一方面,當編譯my.cpp並將其鏈接到libopen62541.a ,編譯器不會看到該冒犯的C代碼,因此不會出現錯誤(警告)。


從這里開始,您基本上有兩個選擇:

  1. 如果適合您,請使用預編譯的庫

     g++ -std=c++14 -Wall -Wextra -Werror my.cpp -lopen62541.a -o out 
  2. 如果需要修改,請先編譯庫的代碼

     gcc -Wall -Wextra -Werror -c open62541.c g++ -std=c++14 -Wall -Wextra -Werror -c my.cpp g++ open62541.o my.o -o out 
gcc -x c++ -std=c++14 -Wall my.cpp open62541.c -lstdc++ -o out

此命令強制將open62541.c的C代碼編譯為C ++。 該文件顯然包含在C中有效的構造,但在C ++中無效。

您應該做的是將每個文件編譯為自己的語言,然后將它們鏈接在一起:

gcc -std=gnu11 -Wall -c open62541.c
g++ -std=gnu++14 -Wall -c my.cpp
g++ -o out my.o open62541.o

將這些命令包裝在易於重復的軟件包中是Makefile的作用。

如果您想知道為什么我從嚴格的-std=c++14更改為寬松的-std=gnu++14模式,那是因為嚴格的模式是如此嚴格,以至於可能破壞系統頭文件! 您無需在所有其他事情上都進行處理。 如果您希望獲得更多實用性的嚴格性,請嘗試添加-Wextra和-Wpedantic ...,但是為此准備好在第三方代碼上拋出很多實際上並不指示錯誤的警告。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM