Naetw / Naetw.github.io

https://naetw.github.io
1 stars 0 forks source link

How C++ Works: Understanding Compilation #2

Open Naetw opened 6 years ago

Naetw commented 6 years ago

How C++ Works: Understanding Compilation

Translation Unit (Compilation Unit)

Name Mangling (Name Decoration)

extern "C"

Sample print.cpp:

#include <iostream>
#include "sum.h" // sumI, sumF

void printSum(int a, int b) {
  std::cout << a << " + " << b << " = " sumI(a, b) << std::endl;
}

void printSum(float a, float b) {
  std::cout << a << " + " << b << " = " sumF(a, b) << std::endl;
}

extern "C" void printSumInt(int a, int b) {
  printSum(a, b);
}

extern "C" void printSumFloat(float a, float b) {
  printSum(a, b);
}

上面程式中,printSum 是一個 overloading function,也就是沒辦法直接被 C 使用,為了給 C 使用,可以用 wrapper function 像是上面的 printSumInt & printSumFloat,並且將它們用 extern "C" 去標註,好讓編譯器不會對他們做 mangling。接著用 nm 來看看 symbols:

$ g++ -c print.cpp
$ nm print.o
0000000000000132 T printSumFloat
0000000000000113 T printSumInt
                 U sumF
                 U sumI
0000000000000074 T _Z8printSumff
0000000000000000 T _Z8printSumii
                 U _ZSt4cout

接著來看看如何設計一個可以給 C & C++ include 的標頭檔,目標是讓 printSumInt & printSumFloat 可以被 C & C++ 呼叫,而 printSum 可以被 C++ 呼叫:

#ifdef __cplusplus
void printSum(int a, int b);
void printSum(float a, float b);
extern "C" {
#endif

void printSumInt(int a, int b);
void printSumFloat(float a, float b);

#ifdef __cplusplus
} // end extern "C"
#endif

Include Guards

#ifndef __GUARDED_HPP
#define __GUARDED_HPP

... 

#endif // __GUARDED_HPP

Forward Declaration

這邊指的是跟 compiler 比較相關議題。

MISC Stuff