จะเกิดอะไรขึ้นถ้าพฤติกรรม C ++ ที่ไม่ได้กำหนดตรงกับพฤติกรรมที่กำหนดไว้ C?


10

ฉันมี*.cppไฟล์ที่คอมไพล์ด้วย C ++ (ไม่ใช่คอมไพเลอร์ C) ฟังก์ชั่นที่มีอยู่อาศัยนักแสดง (ดูบรรทัดสุดท้าย) ซึ่งดูเหมือนว่าจะถูกกำหนดใน C (โปรดแก้ไขถ้าฉันผิด!) แต่ไม่ใช่ใน C ++ สำหรับประเภทพิเศษนี้

[...] C++ code [...]

struct sockaddr_in sa = {0};
int sockfd = ...;
sa.sin_family = AF_INET;
sa.sin_port = htons(port);
bind(sockfd, (struct sockaddr *)&sa, sizeof sa);

[...] C++ code [...]

เนื่องจากฉันคอมไพล์ไฟล์นี้ในไฟล์ C ++ ตอนนี้มันเป็นพฤติกรรมที่กำหนดหรือไม่ได้กำหนดหรือไม่? หรือฉันจะต้องย้ายสิ่งนี้เป็น*.cไฟล์เพื่อให้มันเป็นพฤติกรรมที่กำหนดไว้?


1
นามสกุลไฟล์ไม่มีความหมาย เฉพาะในกรณีที่คุณรวบรวมเป็น C หรือ C ++
Fredrik

1
ประเภทที่เกี่ยวข้องไม่ได้รับการสืบทอดจากกันและกันและไม่มีความสัมพันธ์และไม่ได้กำหนดไว้ใน C ++
Daniel Stephens

1
โดยทั่วไปถ้าไฟล์มี.cนามสกุลคอมไพเลอร์ C จะถูกเรียกใช้โดยอัตโนมัติ
Igor R.

1
ฉันทำอย่างนั้นหลอกตลอดเวลาในรหัส C ++ ไม่รู้เลยว่าทำไมมันถึงไม่เหมาะกับคุณ คิดถึงส่วนหัวอยู่ใช่ไหม
user4581301

3
@DanielStephens โปรแกรมนี้ไม่เคยพยายามที่จะอ้างถึงตัวชี้ อนุญาตให้ใช้ตัวบล็อกตัวเองการลงทะเบียน - บางครั้งเท่านั้น ถ้าด้าน C เหวี่ยงพอยเตอร์กลับไปเป็นของจริงอย่างถูกต้องทุกอย่างน่าจะดี ปัญหาเกี่ยวกับการร่ายอาจจะเกิดขึ้นได้หากประเภทเหล่านั้นมีความต้องการการจัดตำแหน่งที่แตกต่างกัน
user7860670

คำตอบ:


6

สิ่งนี้ถูกกำหนดไว้ในทั้ง C ++ และ C ซึ่งไม่ได้ละเมิดข้อบังคับ aliasing ที่เข้มงวดเนื่องจากไม่ได้ทำการตรวจสอบตัวชี้ผลลัพธ์

นี่คือคำพูดจาก C ++ (ขอบคุณ @interjay และ @VTT) ที่อนุญาตสิ่งนี้:

ตัวชี้วัตถุสามารถแปลงอย่างชัดเจนเป็นตัวชี้วัตถุประเภทอื่น

นี่คือคำพูดจาก C (ขอบคุณ @StoryTeller) ที่อนุญาตสิ่งนี้:

ตัวชี้ชนิดวัตถุอาจถูกแปลงเป็นตัวชี้ชนิดวัตถุอื่น

สิ่งเหล่านี้ระบุว่าหนึ่งประเภทตัวชี้สามารถแปลงเป็นประเภทตัวชี้อื่น (แล้วแปลงกลับเป็นทางเลือก) โดยไม่มีผล

และนี่คือคำพูดจาก POSIXที่อนุญาตกรณีเฉพาะนี้:

sockaddr_inโครงสร้างจะใช้ในการอยู่ร้านสำหรับครอบครัวที่อยู่อินเทอร์เน็ต พอยน์เตอร์สำหรับประเภทนี้จะถูกนำเสนอโดยแอปพลิเคชันเพื่อstruct sockaddr *สำหรับใช้กับฟังก์ชั่นซ็อกเก็ต

เนื่องจากฟังก์ชั่นนี้ ( bind) เป็นส่วนหนึ่งของไลบรารีมาตรฐาน C ไม่ว่าอะไรก็ตามที่อยู่ภายใน


หากต้องการตอบคำถามทั่วไปเพิ่มเติม:

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


1
@interjay คุณช่วยสำรองข้อมูลด้วยการอ้างอิงจากมาตรฐาน (ทั้ง C หรือ C ++ ได้ไหม)
SS Anne


1
@StoryTeller ขอบคุณ เพิ่มเวอร์ชัน HTTP แทน
SS Anne

2
เนื้อหานี้เป็นข้อบกพร่องในมาตรฐาน POSIX - อาร์กิวเมนต์ที่สองที่bindควรเป็นconst void *แต่bindมีการถือกำเนิดของvoidภาษา C (และมีอยู่ของ C ++ เลย) พวกเขาอัปเดตในบางจุดเพื่อเพิ่มconstแต่ไม่เคยแก้ไขประเภทพื้นฐาน
Chris Dodd

1
ฉันสามารถแนะนำการพูดคุยนี้youtube.com/watch?v=_qzMpk-22ccฉันยังไม่แน่ใจว่ามันตรวจสอบคำตอบหรือถ้ามันเป็นจริงพูดตรงข้าม: -o C ++ เป็นฝันร้าย .. lol
Daniel Stephens

-3

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

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


ย่อหน้าแรก: "การโทรระหว่างรหัส C และ C ++ จะเรียกใช้พฤติกรรมที่ไม่ได้กำหนดทั้งหมด"แม้ว่าจะมีสิ่งเช่น "เรียกใช้พฤติกรรมที่ไม่ได้กำหนด" (ซึ่งไม่มี) ก็ยังไม่มีเหตุผล
Lightness Races ที่ Orbit

ย่อหน้าที่สอง: ไม่รู้ว่าคุณกำลังพูดอะไรอยู่
Lightness Races ที่ Orbit

@LightnessRacesinOrbit ฉันคิดว่าคำตอบนี้เป็นผลจากการเพิ่มแท็ก [language-Lawyers] ในคำถาม ตอนนี้ฉันคิดว่ามันดีกว่า (คำตอบมักจะเป็นไปตามตัวอักษรมากเกินไป) และนำออกไป
SS Anne

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