g ++ การอ้างอิงที่ไม่ได้กำหนดไปยัง typeinfo


209

ฉันเพิ่งพบข้อผิดพลาดต่อไปนี้ (และพบวิธีแก้ปัญหาออนไลน์ แต่ไม่มีอยู่ใน Stack Overflow):

(.gnu.linkonce. [stuff]): การอ้างอิงที่ไม่ได้กำหนดถึง [method] [object file] :(. gnu.linkonce. [stuff]): การอ้างอิงที่ไม่ได้กำหนดให้กับ `typeinfo สำหรับ [classname] '

เหตุใดเราจึงอาจได้รับข้อผิดพลาด "การอ้างอิงที่ไม่ได้ระบุถึงตัวเชื่อมโยง typeinfo" อย่างใดอย่างหนึ่งเหล่านี้

(คะแนนโบนัสหากคุณสามารถอธิบายสิ่งที่เกิดขึ้นเบื้องหลัง)


31
ฉันรู้ว่ามันเป็นโพสต์เก่า แต่ฉันมีปัญหาเดียวกันในวันนี้และการแก้ปัญหาคือเพียงเพื่อกำหนดฟังก์ชั่นเสมือนจริงของฉันเป็นเสมือน abc () {} ในคลาสฐานแทนที่จะเป็นเสมือน abc (); ซึ่งทำให้เกิดข้อผิดพลาด
Nav

15
ยังดีกว่าvirtual void abc() =0;(ถ้าเวอร์ชันฐานไม่เคยถูกเรียก)
dhardy

3
@Nav: หากคุณกำหนดabc()เช่นนั้นคุณสามารถลืมกำหนดabc()ในคลาสที่ได้รับมาและคิดว่าทุกอย่างไม่เป็นไรเนื่องจากคุณจะยังสามารถเรียกใช้ฟังก์ชันได้โดยไม่มีปัญหา แนวทางปฏิบัติที่ดีสำหรับการใช้งานฟังก์ชั่นเสมือนล้วนมีอยู่ในบทความนี้และนี่คือการทำให้ฟังก์ชั่นการพิมพ์ "ฟังก์ชั่นเสมือนจริงที่เรียกว่า" และจากนั้นโปรแกรมผิดพลาด
HelloGoodbye

1
ฉันมีข้อผิดพลาดเดียวกัน ฉันพบว่าการเปลี่ยนลำดับการอ้างอิงถึง "lib" อาจช่วยได้ ฉันเพียงแค่ย้ายปัญหา lib จากจุดเริ่มต้นถึงจุดสิ้นสุดของรายการนี้และแก้ปัญหาได้
javapowered

2
GAH อย่างน้อยตอนนี้เป็นครั้งที่สองที่ฉันได้ไปที่หน้านี้เพื่ออ่านความคิดเห็นโดย @dhardy และพูดกับตัวเอง 'Doh' เพียงแค่ใช้เวลา 45minutes = 0;พยายามติดตามพฤติกรรมบางบ้าและฉันทั้งหมดที่จำเป็นคือ
dwanderson

คำตอบ:


223

เหตุผลหนึ่งที่เป็นไปได้คือเนื่องจากคุณประกาศฟังก์ชันเสมือนโดยไม่ต้องกำหนด

เมื่อคุณประกาศโดยไม่กำหนดในหน่วยการคอมไพล์เดียวกันคุณกำลังระบุว่ามันถูกกำหนดไว้ที่อื่นนั่นหมายถึงเฟสตัวเชื่อมโยงจะพยายามค้นหามันในหนึ่งในหน่วยการคอมไพล์อื่น ๆ (หรือไลบรารี)

ตัวอย่างของการนิยามฟังก์ชันเสมือนคือ:

virtual void fn() { /* insert code here */ }

ในกรณีนี้คุณกำลังแนบคำนิยามในการประกาศซึ่งหมายความว่าลิงเกอร์ไม่จำเป็นต้องแก้ไขในภายหลัง

เส้น

virtual void fn();

ประกาศ fn()โดยไม่กำหนดและจะทำให้เกิดข้อความแสดงข้อผิดพลาดที่คุณถาม

มันคล้ายกับรหัสมาก:

extern int i;
int *pi = &i;

ซึ่งระบุว่าจำนวนเต็มiถูกประกาศในหน่วยการรวบรวมอื่นซึ่งจะต้องแก้ไขในเวลาลิงก์ (มิฉะนั้นpiจะไม่สามารถตั้งค่าเป็นที่อยู่ของมัน)


28
มันไม่ถูกต้องที่จะบอกว่าvirtual void fn() = 0เป็นคำจำกัดความ มันไม่ได้เป็นความหมาย แต่เพียงการประกาศ เหตุผลเดียวที่ linker ไม่พยายามแก้ไขคือรายการ VMT ที่เกี่ยวข้องจะไม่อ้างถึงเนื้อหาของฟังก์ชัน (จะมีตัวชี้ null ที่เป็นไปได้มากที่สุด) อย่างไรก็ตามไม่มีใครห้ามไม่ให้คุณเรียกใช้ฟังก์ชันเสมือนบริสุทธิ์นี้ในลักษณะที่ไม่เสมือนเช่นใช้ชื่อที่ผ่านการรับรองโดยสมบูรณ์ ในกรณีนี้ตัวเชื่อมโยงจะค้นหาเนื้อหาและคุณจะต้องกำหนดฟังก์ชัน และใช่คุณสามารถกำหนดร่างกายสำหรับฟังก์ชั่นเสมือนที่บริสุทธิ์
AnTe

1
และบางครั้งเราก็ต้องประกาศเนื้อความสำหรับฟังก์ชั่นเสมือนที่บริสุทธิ์
ทำเครื่องหมาย

3
คอมไพเลอร์ (g ++) จะบอกคุณว่าสัญลักษณ์ที่หายไปคืออะไร หมายเหตุ: ในกรณีของการเชื่อมโยงไลบรารีแบบไดนามิกคุณอาจได้รับชื่อที่ยุ่งเหยิง ใช้ c ++ filt <mangledNameVariable> เพื่อรับมันในรูปแบบที่อ่านได้ ข้อผิดพลาด typeinfo ที่มีชื่อชั้นอยู่ในกรณีของฉันเพราะการใช้งาน destructor เสมือนที่ขาดหายไปในบางชั้นฐาน
chmike

1
คำถามกล่าวถึงเฉพาะว่าเป็น typeinfo ที่หายไปซึ่งเกี่ยวข้องกับ rtti ดูความคิดเห็นจาก Damon ในstackoverflow.com/questions/11904519/ …
wilsonmichaelpatrick

1
@gbmhunter ยุติธรรมพอ ทำการเปลี่ยนแปลง
paxdiablo

150

สิ่งนี้สามารถเกิดขึ้นได้เมื่อคุณมิกซ์-fno-rttiและ-frttiโค้ด แล้วคุณจะต้องมั่นใจว่าระดับใดที่type_infoมีการเข้าถึงในรหัสที่มีวิธีการสำคัญของพวกเขารวบรวมกับ-frtti -frttiการเข้าถึงดังกล่าวสามารถเกิดขึ้นได้เมื่อคุณสร้างวัตถุของคลาสให้ใช้dynamic_castฯลฯ

[ แหล่งที่มา ]


20
ขอบคุณมาก. นั่นช่วยแก้ไขปัญหาของฉันหลังจากค้นหา 5 ชั่วโมง
Steipete

1
แหล่งที่มาของลิงก์นั้นตายแล้วมันก็เหมือนกับpermalink.gmane.org/gmane.comp.gcc.help/32475
คณิตศาสตร์

1
ขอบคุณที่ชี้นำสิ่งนี้ หน้าเดิมยังคงมีอยู่ที่นี่: web.archive.org/web/20100503172629/http://www.pubbs.net/201004/ …
Sergiy Belozorov

3
StackOverflow.com เพื่อช่วยเหลืออีกครั้ง! ฉันหวังว่าฉันจะโหวตได้มากกว่าหนึ่งครั้ง หลังจากต่อสู้กับหัวของฉันบนแป้นพิมพ์เป็นเวลาหนึ่งชั่วโมงคำตอบของคุณคือสิ่งที่ฉันต้องการ
spartygw

1
ชีวิต +1 ของ n + บันทึกไว้และยังคงนับ :)
กาเบรียล

53

สิ่งนี้เกิดขึ้นเมื่อฟังก์ชั่นเสมือนที่ประกาศแล้ว (ไม่บริสุทธิ์) หายไปจากเนื้อความ ในคำจำกัดความของชั้นเรียนมีลักษณะดังนี้:

virtual void foo();

ควรกำหนด (แบบอินไลน์หรือในไฟล์ที่เชื่อมโยง):

virtual void foo() {}

หรือประกาศบริสุทธิ์เสมือน:

virtual void foo() = 0;

27

ข้อความจากคู่มือ gcc :

สำหรับคลาส polymorphic (คลาสที่มีฟังก์ชันเสมือน) วัตถุ type_info จะถูกเขียนออกมาพร้อมกับ vtable [... ] สำหรับประเภทอื่น ๆ ทั้งหมดเราจะเขียนอ็อบเจกต์ type_info เมื่อมันถูกใช้: เมื่อใช้ `typeid 'กับนิพจน์ การขว้างปาวัตถุหรืออ้างอิงถึงประเภทในข้อจับหรือข้อกำหนดข้อยกเว้น

และก่อนหน้านี้เล็กน้อยในหน้าเดียวกัน:

หากคลาสประกาศฟังก์ชันเสมือนที่ไม่ใช่แบบอินไลน์และไม่บริสุทธิ์ฟังก์ชันแรกจะถูกเลือกเป็น "วิธีการหลัก" สำหรับชั้นเรียนและ vtable จะถูกปล่อยออกมาเฉพาะในหน่วยการแปลที่กำหนดวิธีการที่สำคัญ

ดังนั้นข้อผิดพลาดนี้เกิดขึ้นเมื่อ "วิธีการหลัก" ไม่มีคำจำกัดความตามคำตอบอื่น ๆ ที่ได้กล่าวไปแล้ว


2
ในกรณีของฉันฉันมีคลาสพื้นฐานซึ่งประกาศ แต่ไม่ได้กำหนดวิธีการเสมือนที่ไม่เสมือนจริง เมื่อฉันทำให้พวกเขาบริสุทธิ์เสมือนซึ่งเป็นสิ่งที่ฉันหมายถึงข้อผิดพลาด linker หายไป
Tatiana Racheva

@TatianaRacheva ขอบคุณ! การรายงานข้อผิดพลาดจากตัวเชื่อมโยงมีประโยชน์น้อยกว่าและสำหรับอินเทอร์เฟซขนาดใหญ่มันง่ายมากที่จะพลาด '= 0;' เพื่อความเสมือนจริง!
rholmes

21

หากคุณกำลังเชื่อมโยงหนึ่งไปยังอีกรายการหนึ่งความเป็นไปได้อีกอย่างหนึ่งคือการคอมไพล์ด้วย "-fvisibility = hidden" ใน gcc หรือ g ++ หากไฟล์. so ทั้งคู่ถูกสร้างขึ้นด้วย "-fvisibility = hidden" และวิธีการคีย์ไม่เหมือนกันดังนั้นจึงเป็นการใช้งานของฟังก์ชั่นเสมือนอีกอันหนึ่งหลังจะไม่เห็น vtable หรือ typeinfo ของอดีต สำหรับ linker ดูเหมือนว่าฟังก์ชั่นเสมือนที่ยังไม่ได้ใช้งาน (เช่นในคำตอบของ paxdiablo และ cdleary)

ในกรณีนี้คุณต้องสร้างข้อยกเว้นสำหรับการมองเห็นของคลาสฐานด้วย

__attribute__ ((visibility("default")))

ในการประกาศคลาส ตัวอย่างเช่น

class __attribute__ ((visibility("default"))) boom{
    virtual void stick();
}

แน่นอนว่าวิธีแก้ไขปัญหาอื่นคือไม่ใช้ "-fvisibility = hidden" สิ่งนี้ทำให้สิ่งที่ซับซ้อนสำหรับคอมไพเลอร์และลิงเกอร์อาจเป็นผลเสียต่อประสิทธิภาพของโค้ด


1
คุณไม่จำเป็นต้องส่งออก (ยกเลิกการซ่อน) คลาสฐานถ้ามันเป็นนามธรรมหรือไม่ได้ใช้เพียงฟังก์ชั่นที่ไม่ใช่เสมือนปกติเพียงแค่นวกรรมิก มาเรียนในมืออื่น ๆ จะต้องมีการส่งออกถ้าพวกเขาจะใช้
Chris Huang-Leaver

รู้สึกเหมือนแฮ็ค แต่มันแก้อาการข้างฉันได้ ขอบคุณมาก!
malat

16

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

ถ้าคุณต้องการพิมพ์ข้อมูลเพื่อทำงานกับคลาสที่คุณไม่ต้องการฟังก์ชั่นเสมือนจริง ๆ ให้สร้าง destructor เสมือน


2
อัปเดตแล้วเนื่องจากฉันคิดว่านี่น่าจะเป็นสาเหตุของข้อความแสดงข้อผิดพลาดนั้น (เมื่อเทียบกับกรณีทั่วไปของวิธีที่ไม่ได้กำหนด ... )
Alastair

4
สิ่งหนึ่งที่ฉันต้องคุ้นเคยกับ SO นั้นไม่ได้หมายถึงคำตอบ "เหนือ" เนื่องจากคำสั่งซื้ออาจเปลี่ยนแปลงตามการลงคะแนน ปกติฉันไม่ได้อ้างถึงคำตอบอื่น ๆ ในขณะนี้เนื่องจากสามารถลบได้เช่นกัน ความเชื่อของฉันคือคำตอบควรเป็นแบบสแตนด์อโลน ฉันยังคงอ้างถึงชื่อผู้ใช้สำหรับแหล่งที่มาอย่างไรก็ตาม
paxdiablo

คุณสามารถใช้ typeid โดยไม่มี vtable ดูคำตอบของฉันสำหรับคำพูดจากคู่มือ gcc
CesarB

11

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

ฉันกำลังทำงานในโครงการที่รวบรวมโดยใช้ทั้งและclang++ g++ผมมีปัญหาที่ไม่มีการเชื่อมโยงโดยใช้clang++แต่ได้รับข้อผิดพลาดด้วยundefined reference to 'typeinfo forg++

จุดสำคัญ:g++เพื่อเชื่อมโยงโอกาสสำคัญกับ หากคุณแสดงรายการไลบรารีที่คุณต้องการเชื่อมโยงในลำดับที่ไม่ถูกต้องคุณจะได้รับtypeinfoข้อผิดพลาด

ดูคำถาม SO นี้สำหรับรายละเอียดเพิ่มเติมเกี่ยวกับการเชื่อมโยงกับการสั่งซื้อ/gccg++


ขอบคุณ!!! ฉันใช้เวลาทั้งวันพยายามหาสาเหตุว่าทำไมฉันถึงได้รับข้อผิดพลาดนี้และไม่มีอะไรทำงานจนกว่าฉันจะเห็นคำตอบนี้และคำตอบที่คุณเชื่อมโยง ขอบคุณมาก!!
Irene

10

วิธีแก้ปัญหาที่เป็นไปได้สำหรับรหัสที่จัดการกับไลบรารี RTTI และไม่ใช่ RTTI:

a) คอมไพล์ทุกสิ่งด้วย -frtti หรือ -fno-rtti
b) ถ้า a) เป็นไปไม่ได้สำหรับคุณลองต่อไปนี้:

สมมติว่า libfoo สร้างขึ้นโดยไม่มี RTTI รหัสของคุณใช้ libfoo และคอมไพล์ด้วย RTTI หากคุณใช้ class (Foo) ใน libfoo ที่มี virtuals คุณมีโอกาสที่จะพบข้อผิดพลาดเกี่ยวกับลิงก์เวลาที่ระบุว่า: หายไป typeinfo สำหรับ class Foo

กำหนดคลาสอื่น (เช่น FooAdapter) ที่ไม่มีเสมือนและจะโอนสายไปยัง Foo ที่คุณใช้

รวบรวม FooAdapter ในสแตติกไลบรารีขนาดเล็กที่ไม่ได้ใช้ RTTI และขึ้นอยู่กับสัญลักษณ์ libfoo เท่านั้น ระบุส่วนหัวและใช้แทนในรหัสของคุณ (ซึ่งใช้ RTTI) เนื่องจาก FooAdapter ไม่มีฟังก์ชั่นเสมือนจริงมันจะไม่มี typeinfo ใด ๆ และคุณจะสามารถเชื่อมโยงไบนารีของคุณได้ หากคุณใช้คลาสที่แตกต่างกันจำนวนมากจาก libfoo โซลูชันนี้อาจไม่สะดวก แต่เป็นการเริ่มต้น


นี่สำหรับฉันแล้วการลิงก์ไปยังไลบรารีที่มีการตั้งค่า RTTI แตกต่างกัน
มาร์ช

6

เช่นเดียวกับการสนทนา RTTI, NO-RTTI ด้านบนปัญหานี้อาจเกิดขึ้นหากคุณใช้ dynamic_cast และไม่สามารถรวมรหัสวัตถุที่มีการใช้งานคลาสได้

ฉันพบปัญหาในการสร้างบน Cygwin แล้วเปลี่ยนรหัสไปยัง Linux ไฟล์ make โครงสร้างไดเรกทอรีและแม้แต่เวอร์ชัน gcc (4.8.2) เหมือนกันในทั้งสองกรณี แต่โค้ดที่เชื่อมโยงและทำงานอย่างถูกต้องบน Cygwin แต่ไม่สามารถลิงก์บน Linux Red Hat Cygwin ได้ทำการปรับเปลี่ยนคอมไพเลอร์ / ลิงเกอร์ที่หลีกเลี่ยงข้อกำหนดการเชื่อมโยงโค้ดวัตถุ

ข้อความแสดงข้อผิดพลาดของตัวเชื่อมโยง Linux นำฉันไปยังบรรทัด dynamic_cast อย่างถูกต้อง แต่ข้อความก่อนหน้าในฟอรัมนี้ทำให้ฉันมองหาการใช้งานฟังก์ชั่นที่ขาดหายไปแทนที่จะเป็นปัญหาที่เกิดขึ้นจริง: ไม่มีรหัสวัตถุ วิธีแก้ปัญหาของฉันคือการแทนที่ฟังก์ชันประเภทเสมือนในคลาสพื้นฐานและคลาสที่ได้รับเช่น virtual int isSpecialType () แทนที่จะใช้ dynamic_cast เทคนิคนี้หลีกเลี่ยงข้อกำหนดในการเชื่อมโยงรหัสการนำวัตถุไปใช้เพื่อให้ dynamic_cast ทำงานได้อย่างถูกต้อง


5

ในคลาสฐาน (คลาสฐานนามธรรม) คุณประกาศ destructor เสมือนและในขณะที่คุณไม่สามารถประกาศ destructor เป็นฟังก์ชันเสมือนล้วนคุณต้องกำหนดมันที่นี่ในคลาสนามธรรมเพียงนิยามหุ่นจำลองเสมือนฐาน ~ ( ) {} จะทำหรือในชั้นเรียนที่ได้รับมา

หากคุณไม่ทำเช่นนี้คุณจะพบกับ "สัญลักษณ์ที่ไม่ได้กำหนด" ในเวลาลิงก์ เนื่องจาก VMT มีรายการสำหรับฟังก์ชันเสมือนบริสุทธิ์ทั้งหมดที่มี NULL ที่ตรงกันเนื่องจากจะอัพเดตตารางขึ้นอยู่กับการนำไปใช้ในคลาสที่ได้รับมา แต่สำหรับฟังก์ชั่นที่ไม่บริสุทธิ์ แต่เสมือนมันต้องการคำนิยามในเวลาลิงค์เพื่อที่จะสามารถปรับปรุงตาราง VMT

ใช้ฟิลเตอร์ c ++ เพื่อลดความซับซ้อนของสัญลักษณ์ เช่น $ c ++ filt _ZTIN10storageapi8BaseHostE จะส่งออกบางอย่างเช่น "typeinfo สำหรับ storageapi :: BaseHost"


3

ฉันได้รับข้อผิดพลาดมากมายตอนนี้ สิ่งที่เกิดขึ้นคือฉันแบ่งคลาส header-file-only เป็นไฟล์ header และไฟล์ cpp อย่างไรก็ตามฉันไม่ได้อัปเดตระบบการสร้างของฉันดังนั้นไฟล์ cpp จึงไม่ได้รับการรวบรวม ในบรรดาการอ้างอิงที่ไม่ได้กำหนดไปยังฟังก์ชันที่ประกาศในส่วนหัว แต่ไม่ได้นำไปใช้ฉันได้รับข้อผิดพลาด typeinfo เหล่านี้จำนวนมาก

ทางออกคือการสร้างระบบบิลด์ใหม่เพื่อคอมไพล์และเชื่อมโยงไฟล์ cpp ใหม่


3

ในกรณีของฉันฉันใช้ห้องสมุดบุคคลที่สามที่มีไฟล์ส่วนหัวและอื่น ๆ ฉันคลาสย่อยหนึ่งคลาสและข้อผิดพลาดลิงก์เช่นนี้เกิดขึ้นเมื่อฉันพยายามอินสแตนซ์คลาสย่อยของฉัน

ตามที่กล่าวถึงโดย @sergiy การรู้ว่ามันอาจเป็นปัญหาของ 'rtti' ฉันจัดการเพื่อแก้ไขมันโดยการนำคอนสตรัคเตอร์ไปใช้ในไฟล์. cpp ที่แยกต่างหากและใช้แฟล็กคอมไพล์ '-fno-rtti' กับไฟล์รวบรวมธงไปยังแฟ้ม มันทำงานได้ดี

เนื่องจากฉันยังไม่ค่อยชัดเจนเกี่ยวกับข้อผิดพลาดในการเชื่อมโยงนี้ฉันไม่แน่ใจว่าโซลูชันของฉันเป็นแบบทั่วไปหรือไม่ อย่างไรก็ตามฉันคิดว่ามันคุ้มค่ากับการยิงก่อนที่จะลองใช้อะแดปเตอร์ตามที่ @francois และแน่นอนถ้ามีซอร์สโค้ดทั้งหมด (ไม่ใช่ในกรณีของฉัน) ให้ทำการคอมไพล์ใหม่ด้วย '-frtti' ถ้าเป็นไปได้

อีกอย่างหนึ่งถ้าคุณเลือกที่จะลองใช้วิธีแก้ปัญหาของฉันลองสร้างไฟล์แยกกันให้ง่ายที่สุดและอย่าใช้ฟีเจอร์แฟนซีของ C ++ ให้ความสนใจเป็นพิเศษกับสิ่งที่เกี่ยวข้องกับการเพิ่มทำให้มากขึ้นอยู่กับ rtti


2

ฉันมีข้อผิดพลาดเดียวกันเมื่ออินเทอร์เฟซของฉัน (ด้วยฟังก์ชั่นเสมือนจริงทั้งหมด) ต้องการฟังก์ชั่นเพิ่มอีกหนึ่งฟังก์ชั่นและฉันลืม "null"

ฉันมี

class ICommProvider { public: /** * @brief If connection is established, it sends the message into the server. * @param[in] msg - message to be send * @return 0 if success, error otherwise */ virtual int vaSend(const std::string &msg) = 0; /** * @brief If connection is established, it is waiting will server response back. * @param[out] msg is the message received from server * @return 0 if success, error otherwise */ virtual int vaReceive(std::string &msg) = 0; virtual int vaSendRaw(const char *buff, int bufflen) = 0; virtual int vaReceiveRaw(char *buff, int bufflen) = 0; /** * @bief Closes current connection (if needed) after serving * @return 0 if success, error otherwise */ virtual int vaClose(); };

ล่าสุด vaClose ไม่เสมือนการรวบรวมจึงไม่ทราบว่าจะใช้งานได้ที่ไหนและทำให้สับสน ข้อความของฉันคือ:

... TCPClient.o :(. rodata + 0x38): การอ้างอิงที่ไม่ได้กำหนดเพื่อ `typeinfo สำหรับ ICommProvider '

เปลี่ยนง่ายจาก

virtual int vaClose();

ถึง

virtual int vaClose() = 0;

แก้ไขปัญหา หวังว่ามันจะช่วย


1

ฉันพบสถานการณ์ที่หายาก แต่สิ่งนี้อาจช่วยเพื่อนคนอื่น ๆ ในสถานการณ์ที่คล้ายคลึงกัน ฉันต้องทำงานกับระบบเก่าด้วย gcc 4.4.7 ฉันต้องคอมไพล์โค้ดด้วยการสนับสนุน c ++ 11 ขึ้นไปดังนั้นฉันจึงสร้าง gcc 5.3.0 เวอร์ชันล่าสุด เมื่อสร้างรหัสของฉันและการเชื่อมโยงไปยังการพึ่งพาหากการพึ่งพาเป็นการสร้างด้วยคอมไพเลอร์รุ่นเก่าฉันได้รับข้อผิดพลาด 'undefined Reference to' ถึงแม้ว่าฉันจะกำหนดเส้นทางการเชื่อมโยงอย่างชัดเจนด้วย -L ​​/ path / to / lib -llibname แพคเกจบางอย่างเช่นการเพิ่มและโครงการสร้างด้วย cmake มักจะมีแนวโน้มที่จะใช้คอมไพเลอร์รุ่นเก่าและพวกเขามักจะทำให้เกิดปัญหาดังกล่าว คุณต้องไปไกลเพื่อให้แน่ใจว่าพวกเขาใช้คอมไพเลอร์รุ่นใหม่


1

ในกรณีของฉันมันเป็นปัญหาการพึ่งพาไลบรารีหมดจดแม้ว่าฉันจะมีการเรียก dynamic_cast หลังจากเพิ่มการพึ่งพาพอลงใน makefile ปัญหานี้ได้หายไป


0

ตรวจสอบว่าการอ้างอิงของคุณรวบรวมโดยไม่มี -f-norttiตรวจสอบว่าการอ้างอิงของคุณถูกรวบรวมโดยไม่ต้อง

สำหรับบางโครงการคุณต้องกำหนดอย่างชัดเจนเช่นใน RocksDB:

USE_RTTI=1 make shared_lib -j4

0

ในกรณีของฉันมันเป็นฟังก์ชั่นเสมือนจริงในคลาสอินเตอร์เฟสที่ไม่ได้กำหนดว่าเป็นเสมือนจริง

class IInterface
{
public:
  virtual void Foo() = 0;
}

ฉันลืมไป= 0เล็กน้อย

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.