函數(shù)原型里的外部“C”聲明強(qiáng)制要求用于該函數(shù)的C連接(C linkage),而不是缺省的C++連接(C++ linkage)。這就意味著C連接會(huì)保證可以從使用其它編程語言寫成的模塊里調(diào)用一個(gè)函數(shù)??例如C、Fortran和COBOL??因?yàn)楹瘮?shù)名是以一種大多數(shù)非C++的編譯器和連接器都很熟悉的方式修飾的。
一個(gè)有趣的問題是,將靜態(tài)成員函數(shù)的聲明作為外部“C”是否被允許。例如:
struct C
{
??extern "C" static void f(int); // valid?
};
答案是不行。C++的標(biāo)準(zhǔn)是不允許成員函數(shù),不論是靜態(tài)的還是非靜態(tài)的,被作為外部“C”聲明。第一眼看上去,這個(gè)決定似乎過于嚴(yán)厲,因?yàn)槟銜?huì)把指向靜態(tài)成員函數(shù)的指針作為普通函數(shù)的指針來對待,如下面的例子所示:
void (*pf) (int) = &C::f;
// OK
名稱修飾
你不能將靜態(tài)成員函數(shù)作為外部“C”來聲明有一個(gè)很合理的理由:名稱修飾(也叫做name mangling)。C++的名稱修飾是編譯器將函數(shù)的名稱轉(zhuǎn)變成為一個(gè)唯一的字符串的過程,這個(gè)字符串會(huì)對函數(shù)的類、其命名空間、其參數(shù)表,以及其他等等進(jìn)行編碼。C++的命名修飾適用于靜態(tài)成員函數(shù),也適用于非靜態(tài)成員函數(shù)。靜態(tài)函數(shù)的命名修飾的一個(gè)好處之一,是能夠在不同的類里使用同一個(gè)名稱來聲明兩個(gè)或者更多的靜態(tài)成員函數(shù)??而不會(huì)發(fā)生名稱上的沖突??紤]一下下面的情況:
struct C
{
??static void f(int);
};
struct D
{
??static void f(int); // doesn't clash with C::f
};
f()的外部“C”聲明會(huì)禁止命名修飾;如果它被允許的話,那么不同類里具有相同名稱的靜態(tài)成員函數(shù)就會(huì)相互沖突。它的不足之處是,你不能從使用其它語言寫成的模塊里調(diào)用這些函數(shù),因?yàn)樗鼈冇蠧++連接。]
=========================================================
本文作者Danny Kalev 是一個(gè)系統(tǒng)分析家、軟件工程師,在C++和面向?qū)ο笤O(shè)計(jì)方面有著14年的專業(yè)經(jīng)驗(yàn)。