การพกพาภาษา C


10

ความสะดวกในการพกพาของภาษาอย่าง C นั้นถูกกำหนดอย่างไร? ฉันได้เรียนรู้ว่าคอมไพเลอร์เฉพาะ ISA หากเป็นจริง C พกพาได้อย่างไร? หรือว่าเป็นเพียงซอร์สโค้ดที่เขียนใน C เป็นแบบพกพา แต่ไม่ใช่ไฟล์ปฏิบัติการ? ISA ของ executables ที่เฉพาะเจาะจงสำหรับตัวอย่างแอปพลิเคชันสำหรับ x86 ไม่ได้แยกจากแอปพลิเคชันสำหรับ Apple (สมมติว่า Apple ใช้ไมโครโปรเซสเซอร์ Motorola / PowerPC)

คำตอบ:


27

มันเป็นเพียงรหัสแหล่งที่มาที่เขียนใน C พกพาไม่ได้ปฏิบัติการ?

แก้ไข. บางคนเรียกมันว่าเขียนครั้งเดียวรวบรวมได้ทุกที่

http://en.wikipedia.org/wiki/Write_once,_compile_anywhere

อีกทางเลือกหนึ่งคือเขียนครั้งเดียวทำงานได้ทุกที่ Java เป็นตัวอย่างที่ดีของสิ่งนี้

http://en.wikipedia.org/wiki/Write_once,_run_anywhere

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


ซอร์สโค้ด C ไม่สามารถพกพาไปยังคอมไพเลอร์ที่แตกต่างกันหรือ ISA หรือ OSes ได้โดยไม่ต้องใช้ shennanigans ภาษาอื่น ๆ สิ่งง่าย ๆ เช่นขนาดและการจัดแนวของประเภทมาตรฐานไม่ใช่มาตรฐานใน C ดังนั้นการย้ายซอฟต์แวร์ที่จะแลกเปลี่ยนข้อมูลกับอินสแตนซ์อื่น ๆ ของตัวเองนั้นค่อนข้างท้าทาย อ้างถึง GNU Autoconf / Automake สำหรับตัวอย่าง (อาจสับสน) ของโปรแกรมเมอร์ hoops C จะข้ามผ่านเพื่อให้ได้พกพา
ทิม Williscroft

3
@TimWilliscroft: ปัญหาการพกพามักจะเกิดจากไลบรารีที่ไม่ได้มาตรฐานและวิธีปฏิบัติในการเขียนโปรแกรมที่ไม่ดี และไม่ได้เกิดจาก C หรือไลบรารีมาตรฐาน ตัวอย่างง่ายๆคือการใช้ส่วนขยาย GCC ที่ไม่ได้มาตรฐานหรือความล้มเหลวในการทำให้เป็นอนุกรมข้อมูล / ยกเลิกการทำให้เป็นอนุกรมสำหรับ IO
เบรนแดน

6

มันไม่ได้เป็นเพียงเฉพาะ ISA ตัวอย่างเช่นคุณถาม:

แอปพลิเคชันสำหรับ x86 แยกจากแอปพลิเคชันสำหรับ apple หรือไม่

ใช่มันคือแม้ว่า Apple ใช้ฮาร์ดแวร์ x86 C ไบนารีเป็นสถาปัตยกรรมและระบบปฏิบัติการเฉพาะ


1
@ Steven314: ความคิดเห็นของคุณเป็นแทนเจนต์ มันไม่มีอะไรเกี่ยวข้องกับฮาร์ดแวร์ไม่ว่าจะเป็นมาตรฐานหรือไม่และทุกสิ่งที่เกี่ยวข้องกับความจริงที่ว่า OS X มีรูปแบบไบนารี่ (Mach-O) ที่แตกต่างจากที่กล่าวคือ Linux (โดยทั่วไปคือ ELF)
mipadi

@Steve: EFI กับ BIOS นั้นสำคัญสำหรับการบูทและระบบปฏิบัติการภายในเท่านั้น สถาปัตยกรรมฮาร์ดแวร์ซึ่งเป็นชุดคำสั่ง CPU เหมือนกันเพราะเป็น CPU เดียวกัน
vartec

ความคิดเห็นถูกลบส่วนใหญ่เป็นเพราะฉันไม่ควรรวมสิ่ง mac ไว้ตั้งแต่แรก การกล่าวถึง ABI ของฉัน (Application Binary Interface) และแผนการโทรอาจยังคงเกี่ยวข้อง (รายการที่สามเพื่อเพิ่มไปยัง "สถาปัตยกรรมและระบบปฏิบัติการ") พวกเขาไม่ได้เกี่ยวข้องกับฮาร์ดแวร์ยกเว้นใน ABIs ที่มีแนวโน้มที่จะได้รับการออกแบบสำหรับสถาปัตยกรรมเฉพาะ (เช่นการลงทะเบียนที่มี) แต่พวกเขามีความเกี่ยวข้องกับการพกพาแบบไบนารี นี่ไม่ใช่ปัญหารูปแบบไฟล์ - มีการใช้ ELF ใน Windows และ Linux (โดย gcc) แต่คุณอาจไม่สามารถใช้ไฟล์วัตถุจากที่หนึ่งไปยังอีกที่หนึ่งได้
Steve314

@vartec คุณบอกว่า C ไบนารีเป็นระบบปฏิบัติการที่เฉพาะเจาะจงด้วยเช่นกันเพราะ O / S นั้นเป็นของ ISA เฉพาะดังนั้น C ไบนารีจึงกลายเป็น O / S เฉพาะทางอ้อม
KawaiKx

@Saurabh - ไฟล์พื้นเมืองทั้งหมดเป็นระบบปฏิบัติการที่เฉพาะเจาะจงเพราะ OS ระบุรูปแบบไฟล์ นอกจากนี้ไลบรารีมาตรฐาน C ต้องใช้งานหลายฟังก์ชั่นโดยการเรียกระบบปฏิบัติการดังนั้นแม้ว่ารูปแบบไฟล์จะเป็นมาตรฐานรหัสตัวเองก็ไม่สามารถทำงานบนระบบปฏิบัติการอื่นได้ นี่เป็นมาตรฐานสำหรับภาษาที่คอมไพล์รหัสเนทีฟซึ่งตรงข้ามกับรหัสเครื่องเสมือนบางอย่างเช่น JVM (Java Virtual Machine) เป็นไปได้ที่จะรวบรวม C สำหรับเครื่องเสมือน แต่ไม่เคยทำอย่างที่ฉันรู้ LLVM เข้ามาใกล้ที่สุด แต่มีจุดประสงค์เพื่อเป็นคอมไพเลอร์แบ็คเอนด์ไม่ใช่สภาพแวดล้อมแบบคอมไพล์ครั้งเดียววิ่งได้ทุกที่
Steve314

5

มันเป็นเพียงรหัสแหล่งที่มาที่เขียนใน C พกพาไม่ได้ปฏิบัติการ?

เผง คุณต้องคอมไพล์โปรแกรม C ของคุณอีกครั้งในทุกแพลตฟอร์ม คอมไพเลอร์ C สร้างรหัสเครื่องซึ่งสามารถพกพาได้ในระดับที่ จำกัด มากระหว่างเครื่องของสถาปัตยกรรมโปรเซสเซอร์ / หน่วยความจำเดียวกันและระบบปฏิบัติการ นั่นคือเหตุผลที่คุณเห็นการแจกแจงแบบไบนารีที่แตกต่างกันของแอพหลายแพลตฟอร์ม (เช่นเบราว์เซอร์) เช่น "Linux 64 บิต Intel" หรือ "Mac OS X 32 บิต PowerPC" (ตกลงล่าสุดเป็นเพียงภาพประกอบฉันรู้ว่า Apple เปลี่ยน ถึง Intel เมื่อไม่กี่ปีที่ผ่านมา :-)


3

ตอบคำถามส่วนใหญ่แล้ว แต่ฉันต้องการเพิ่มมากกว่าความทนทานเป็นอีกสิ่งหนึ่งที่คุณอาจต้องคำนึงถึง

ตัวอย่างเช่น JAVA สามารถเขียนได้หนึ่งครั้งและเรียกใช้บนแพลตฟอร์มใด ๆ ที่ VM (วันนี้เรียกว่า "สภาพแวดล้อมรันไทม์") แต่ข้อดีอีกอย่างคือคุณสามารถรันโค้ด Java 1.1 จาก 1995 ในเครื่อง 2011 ของคุณ ซึ่งเป็นไปไม่ได้หากโค้ดของคุณถูกคอมไพล์บน i386 และคุณพยายามรันบนสถาปัตยกรรม AMD64 ของคุณ

คุณได้รับการปรับปรุงของเครื่องเสมือนจริงด้วยเช่นกัน

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

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


3

คำตอบที่ดีเกี่ยวกับการเขียนครั้งเดียวรวบรวมได้ทุกที่

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

ดังนั้นฉันจะบอกได้ว่าการพกพาของภาษานั้นถูกกำหนดโดย:

  1. ระดับมาตรฐาน
  2. ความพร้อมใช้งานของคอมไพเลอร์สำหรับแพลตฟอร์ม / สถาปัตยกรรมต่างๆ
  3. ความลึกและความกว้างของห้องสมุดพกพา

แม้ว่าจริงแล้วแอปพลิเคชั่น C ที่ซับซ้อนเกือบทั้งหมดจะต้องใช้งานบางอย่างเพื่อย้ายไปยังแพลตฟอร์มใหม่เนื่องจากการพึ่งพาฮาร์ดแวร์หรือระบบปฏิบัติการ กระบวนการนั้นเรียกว่าการย้ายระบบ


3

"การพกพา" มีความหมายหลายอย่าง ด้วยความเคารพต่อ C หมายถึงสิ่งต่อไปนี้:

  • คอมไพเลอร์ถูกนำไปใช้กับ C สำหรับแพลตฟอร์มฮาร์ดแวร์และระบบปฏิบัติการที่หลากหลายซึ่งเป็นข้อตกลงครั้งใหญ่ในช่วงต้นยุค 70

  • มีมาตรฐานที่ตกลงกันโดยทั่วไปสำหรับภาษานั้น ๆ เมื่อเทียบกับการใช้งานคอมไพเลอร์แต่ละครั้งเพื่อให้เข้าใจถึงความแตกต่างของภาษาที่แตกต่างกันเล็กน้อย (อีกครั้งข้อตกลงครั้งใหญ่เมื่อ C ได้รับการออกแบบเป็นครั้งแรก ที่ไม่ได้รับการยอมรับในระดับสากล);

  • เนื่องจากมาตรฐานนี้รหัสที่สอดคล้องกันจะสร้างลักษณะการทำงานเดียวกันเมื่อรวบรวมบนแพลตฟอร์มที่แตกต่างกัน

รหัสที่มาเป็นแบบพกพา แต่ไบนารีใหม่จะต้องมีการสร้างขึ้นสำหรับแต่ละเป้าหมาย

อย่างไรก็ตามโปรดทราบว่าแหล่ง C นั้นไม่ค่อยพกพาได้ง่าย แอปพลิเคชันส่วนใหญ่ต้องการให้คุณก้าวข้ามสิ่งที่กำหนดโดยมาตรฐานภาษาโดยใช้ส่วนขยายที่ไม่ซ้ำกับแพลตฟอร์มเฉพาะดังนั้นในทางปฏิบัติซอร์สโค้ดไม่ได้พกพาได้ 100%

อย่างไรก็ตามโปรดทราบว่า C ค่อนข้างปล่อยให้การนำไปปฏิบัติค่อนข้างมาก ขนาดที่แน่นอนของชนิดข้อมูลต่าง ๆ ลักษณะการทำงานของการโอเวอร์โฟลว์ ฯลฯ ขึ้นอยู่กับการนำไปใช้งาน มาตรฐานให้ข้อกำหนดขั้นต่ำที่การดำเนินการต้องปฏิบัติตาม แต่การดำเนินการนั้นมีอิสระที่จะก้าวข้ามขีด จำกัด เหล่านั้น


0

ไม่ว่า ISA นั้นคืออะไร C ก็ไม่เจาะจง ISA ฉันถือว่าคุณไม่ได้อ้างถึงสล็อตที่ล้าสมัยในปัจจุบันสำหรับการ์ดส่วนขยาย PC

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

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

ซึ่งแตกต่างจากบางภาษา C ไม่ได้มาพร้อมกับไลบรารีขนาดใหญ่ที่ Java หรือ C # ให้ คุณสามารถดึงไลบรารี่ที่พกพาได้ไปทำอะไรก็ได้ แต่คุณต้องทำงานบางอย่างเพื่อสร้างมันและทำให้มันทำงานร่วมกันได้

แน่นอนว่า C มีไลบรารี่มาตรฐาน แต่ขอบเขตค่อนข้าง จำกัด เมื่อเทียบกับ Java, C #, Python และอื่น ๆ


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