Computer >> คอมพิวเตอร์ >  >> การเขียนโปรแกรม >> การเขียนโปรแกรม C

ตั้งชื่อ Mangling และ extern “C” ใน C++


ใน C ++ เราสามารถใช้คุณสมบัติการโอเวอร์โหลดได้ การใช้คุณสมบัตินี้ เราสามารถสร้างฟังก์ชันที่มีชื่อเดียวกันได้ ข้อแตกต่างเพียงอย่างเดียวคือประเภทของอาร์กิวเมนต์และจำนวนอาร์กิวเมนต์ ไม่พิจารณาประเภทการคืนสินค้าที่นี่ ตอนนี้คำถามมาว่า C++ แยกฟังก์ชั่นโอเวอร์โหลดในโค้ดอ็อบเจ็กต์ได้อย่างไร

ในโค้ดอ็อบเจ็กต์ จะเปลี่ยนชื่อโดยเพิ่มข้อมูลเกี่ยวกับอาร์กิวเมนต์ เทคนิคที่ใช้ที่นี่เรียกว่า Name Mangling C ++ ไม่มีเทคนิคมาตรฐานสำหรับการจัดการชื่อ คอมไพเลอร์ที่แตกต่างกันจึงใช้เทคนิคต่างกัน

นี่คือตัวอย่างของ Name Mangling ฟังก์ชันโอเวอร์โหลดมีชื่อว่า func() และฟังก์ชันอื่น my_function() อยู่ที่นั่น

ตัวอย่าง

int func(int x) {
   return x*x;
}
double func(double x) {
   return x*x;
}
void my_function(void) {
   int x = func(2); //integer
   double y = func(2.58); //double
}

คอมไพเลอร์ C++ บางตัวจะเปลี่ยนเป็นด้านล่าง -

ตัวอย่าง

int __func_i(int x) {
   return x*x;
}
double __func_d(double x) {
   return x*x;
}
void __my_function_v(void) {
   int x = __func_i(2); //integer
   double y = __func_d(2.58); //double
}

ตัว C ไม่รองรับฟังก์ชั่นโอเวอร์โหลด ดังนั้นเราต้องแน่ใจว่าชื่อของสัญลักษณ์จะไม่เปลี่ยนแปลง เมื่อเราเชื่อมโยงโค้ด C ใน C++ รหัส C++ ต่อไปนี้จะทำให้เกิดข้อผิดพลาด

ตัวอย่าง

int printf(const char *format,...);
main() {
   printf("Hello World");
}

ผลลัพธ์

undefined reference to `printf(char const*, ...)'
ld returned 1 exit status

ปัญหานี้กำลังเกิดขึ้นเนื่องจากชื่อของ printf() ถูกเปลี่ยนโดยคอมไพเลอร์ และไม่พบคำจำกัดความของฟังก์ชัน printf() ที่อัปเดต เพื่อแก้ปัญหานี้ เราต้องใช้ extern “C” ใน C++ เมื่อใช้โค้ดบางตัวในบล็อกนี้ คอมไพเลอร์ C++ จะทำให้แน่ใจว่าชื่อฟังก์ชันนั้นไม่ถูกแก้ไข จึงไม่เปลี่ยนชื่อ ดังนั้นโค้ดด้านบนจะเป็นแบบนี้เพื่อแก้ปัญหานี้

ตัวอย่าง

extern "C" {
   int printf(const char *format,...);
}
main() {
   printf("Hello World");
}

ผลลัพธ์

Hello World

หมายเหตุ: บล็อกของรหัสเหล่านี้อาจสร้างผลลัพธ์ที่แตกต่างกันในคอมไพเลอร์ที่แตกต่างกัน