gcc將C程序編譯爲C和C++程序,因此需要在C++中聲明'extern「C」'。然而,g ++將C程序編譯爲C++,將C++程序編譯爲C++,因此要求在C++中不要使用'extern「C」'聲明。#ifdef標誌告訴gcc和g ++編譯器之間的區別?
檢查標準標誌沒有任何輸入,無論是
g++ -E -dM - </dev/null
gcc -E -dM - </dev/null
給出了相同的結果。
__GNUG__ is equivalent to testing (__GNUC__ && __cplusplus)
這再次將從克++ 一個C++源內不分化的gcc上市。
什麼是魔術
#ifndef __MAGIC_G++_INCLUDE_FLAG_BUT_NOT_GCC__
到環繞的extern 「C」{聲明?謝謝。
編輯:我知道這是一個相當深奧的情況。該測試需要在編譯器上完成,而不是源代碼的風味。在這兩種情況下,測試都在C++源代碼列表中執行(這就是爲什麼我提到GNUG不合適)。爲了澄清,測試main.cpp中:
#include <iostream>
int
main(int argc, char **argv)
{
#ifdef __cplusplus <<<< FIX THIS ONE
std::cout << "I was compiled using g++" << std::endl;
#else
std::cout << "I was compiled using gcc" << std::endl;
#endif
}
與時任
g++ main.cpp
或在這兩種情況下
gcc main.cpp -lstdc++
,它似乎不正確地給作爲輸出「我整理是用g ++編譯的「。所以看起來cplusplus不是在這種情況下使用的正確標誌。我錯了嗎?或者什麼是正確的標誌?
編輯2: 謝謝,夥計們。這是你的一個例子。大型遺留系統「Alpha」主要以C語言編寫,帶有一點C++,並使用C++編寫的大型遺留源代碼包「Charlie」。它使用g ++系統進行編譯和鏈接,並要求查理的頭文件中沒有外部「C」定義,否則拒絕鏈接。大型遺留系統「Bravo」主要以C編寫,帶有一點C++,並且使用與C++編寫的相同的傳統源代碼包Charlie。它使用gcc系統進行編譯和鏈接,並要求查理的頭文件必須具有外部「C」定義,否則拒絕鏈接。新系統「Delta」,「Echo」和「Foxtrot」也想重用Charlie的部分源代碼,編譯器的使用是不確定的。正確的答案是徹底破解查理的標題,一勞永逸,用
#ifndef __MAGIC_G++_INCLUDE_FLAG_BUT_NOT_GCC__
extern "C" {
#endif
...
declarations of code
...
#ifndef __MAGIC_G++_INCLUDE_FLAG_BUT_NOT_GCC__
}
#endif
然後用它做。否則總會有鏈接問題。是的,當然可以在這種特殊情況下編譯兩套庫,一套在C下,另一套在C++協議下,然後規定你應該使用這個特定的庫來處理這種特殊的鏈接。或者我可以想出兩套標題。在這個例子中,這兩者中的任何一個都不夠優雅,並且會繼續引發問題;還有其他的情況。至於g ++和gcc在底層使用同一個編譯器的評論,所以它不可能很重要,可悲的是,它確實如此。當包含錯誤的'extern'C''教條時,整個程序包拒絕鏈接。是的,還有其他方法可以攻擊一般問題,但這是一個簡單的問題。要麼存在這樣的旗幟,要麼已知它不存在,或者答案不明確。我不知道,我自己。
有一個原因,你需要知道的?你的構建腳本/過程/等等。不是gcc/g ++編譯器的標準嗎? – sedavidw 2014-09-18 18:29:40
您應該使用'gcc'命令編譯C源文件,'g ++'命令編譯C++源文件。你有這樣的理由嗎? – 2014-09-18 18:32:26
'__cplusplus'是爲C++定義的,但不適用於C語言。無論如何,兩個驅動程序('gcc'和'g ++'都是真正編譯器的包裝器)都可以用來編譯C和C++源代碼,儘管它們默認使用不同的標誌,最適合於C和C++。 – Deduplicator 2014-09-18 18:33:11