extern關鍵字
extern
關鍵字是C語言裡已有的特性。
在TensorRT/samples/common/logger.h
中,使用extern
關鍵字"宣告"(注意不是定義)了以下變數:
extern Logger gLogger;
extern LogStreamConsumer gLogVerbose;
extern LogStreamConsumer gLogInfo;
extern LogStreamConsumer gLogWarning;
extern LogStreamConsumer gLogError;
extern LogStreamConsumer gLogFatal;
上面這些變數尚未被定義,但是顯然它們必須被定義一次(且只能被定義一次)。在TensorRT/samples/common/logger.cpp
中便"定義"了這些變數(在這個過程中會為他們分配記憶體):
Logger gLogger{Logger::Severity::kINFO};
LogStreamConsumer gLogVerbose{LOG_VERBOSE(gLogger)};
LogStreamConsumer gLogInfo{LOG_INFO(gLogger)};
LogStreamConsumer gLogWarning{LOG_WARN(gLogger)};
LogStreamConsumer gLogError{LOG_ERROR(gLogger)};
LogStreamConsumer gLogFatal{LOG_FATAL(gLogger)};
由於extern
使得這些變數可以被其它檔案看到,因此在TensorRT/samples/opensource/sampleMNIST/sampleMNIST.cpp
才可以使用gLogger
這個變數:
#include "logger.h"
//...
bool SampleMNIST::build()
{
auto builder = SampleUniquePtr<nvinfer1::IBuilder>(nvinfer1::createInferBuilder(gLogger.getTRTLogger()));
//...
}
我們知道extern
能使一個變數被其它檔案看到,而直接在logger.h
裡"定義"這些變數也可以達到一樣的效果,那麼為什麼我們不這樣做呢?這是因為在編譯後,每個引用 logger.h
的 compilation unit裡都會有一份該變數的定義,到了link的時候,就會出現multiple definition error
,更多範例詳見Demo of “extern” keyword in C。