Apa yang membuat program (dalam bahasa seperti C ++) lintas-platform atau tidak?

8

Saya memiliki pengalaman pemrograman yang cukup mendasar dengan Java dan saya sudah mencoba C ++ dan Python. Meskipun masuk akal untuk Java, program dasar yang saya tulis dalam C ++ telah berjalan dengan baik di Windows dan OS X. Saya sudah bisa mengirim file sumber ke komputer lain, kompilasi, dan jalankan. Programnya cukup mendasar, sebagian besar hanya hal-hal berorientasi objek dasar yang telah saya lakukan untuk mencoba belajar C ++.

Namun jelas, Anda tidak bisa hanya mengkompilasi program C ++ pada mesin apa pun dan menjalankannya dengan baik. Pada titik apa hal itu terjadi? Pada tingkat kerumitan apa platform mulai penting dan program tidak akan berjalan di mana saja? Apakah itu saat Anda menggunakan pustaka khusus platform? Bisakah sebuah program dibuat lintas platform dalam C ++ hanya menggunakan pustaka lintas platform?

Saya sudah mencoba mencari tahu sendiri, tetapi semua yang saya temukan baik di luar kepala saya atau hanya tidak menjawab pertanyaan, banyak yang muncul adalah emulator atau orang yang bertanya apa bahasa lintas platform.

Chris
sumber
2
Pustaka khusus platform, ekstensi kompiler tidak standar, ketergantungan pada bagaimana bit sebenarnya diletakkan dalam memori, dan segala bentuk perilaku tidak terdefinisi / tidak spesifik adalah alasan khas yang saya tahu tentang kode untuk menjadi platform spesifik. Jika Anda menghindari semua itu, ya C ++ cukup portabel secara default.
Ixrec
"Bisakah sebuah program dibuat lintas platform dalam C ++ hanya menggunakan pustaka lintas platform?" Ini sebagian besar benar. Anda juga perlu mengkompilasi (membuat binari) untuk setiap platform karena kode mesin yang dikompilasi khusus untuk arsitektur.
rwong
1
Anda bisa menggunakan kerangka kerja Qt atau POCO .
Basile Starynkevitch

Jawaban:

6

Ada garis yang sangat jelas di antara platform silang dan platform tunggal:

Apakah program hanya menggunakan API yang diekspos oleh Perpustakaan Standar tempat program itu dibangun?

Jika Anda menargetkan implementasi standar, maka setiap platform yang mengimplementasikan standar itu harus, secara teori, mengkompilasi dan menjalankan program Anda dengan benar. Ada banyak pengecualian, tetapi secara umum jika Anda menghindari trik pintar, Anda harus dapat menghindari banyak dari pengecualian itu.

Alasan mengapa masalah ini muncul secara khusus dengan C ++ adalah karena untuk waktu yang lama C ++ Standard Library tidak menyertakan banyak modul yang berguna untuk program non-sepele. Concurrency dan GUI adalah dua yang besar. Ini berarti bahwa program yang dibangun hanya menggunakan C ++ Standard Library tidak dapat memiliki banyak fitur yang kami harapkan dari perangkat lunak modern.

Bagaimana kita menulis perangkat lunak lintas platform yang melakukan hal-hal yang tidak didukung oleh Perpustakaan Standar?

Anda menyebutkan "pustaka lintas platform," yang dalam praktiknya biasanya disebut "kerangka kerja" atau "toolkit" berdasarkan cakupannya. Cara menulis perangkat lunak dalam C ++ yang bersifat lintas platform adalah dengan menargetkan tidak hanya Perpustakaan Standar, tetapi juga kerangka kerja yang dibangun di atas platform target Anda.

Pada dasarnya, Anda akhirnya mengeksternalisasi bit khusus platform ke pustaka lain. Misalnya, wxWidgets adalah kerangka kerja populer. Anda dapat menggunakan kelasnya untuk membuat GUI dan fungsionalitas terkait (mis. Dialog standar untuk memilih file). Di bawah penutup, ia menggunakan kompilasi bersyarat untuk mengimplementasikan GUI menggunakan GUI asli untuk setiap platform. Tetapi sebagai pengguna perpustakaan, tidak ada yang penting bagi Anda.


Catatan sejarah: di sini pada 2015 kompiler dan pustaka C ++, sebagian besar, sangat bagus. Kembali beberapa tahun, dan itu tidak benar. C ++ tidak memiliki standar resmi sampai tahun 1998, bertahun-tahun setelah didirikan. Butuh vendor lama untuk memperbarui kompiler dan perpustakaan mereka untuk menerapkan standar dengan benar. Ekstensi khusus vendor berlimpah (dan masih ada, sebenarnya). Beberapa kompiler memiliki header dan fungsi yang tidak standar. Portabilitas kode hampir tidak ada. Reputasi C ++ dalam hal portabilitas masih menderita.


sumber
5

Pada tingkat kerumitan apa platform mulai penting dan program tidak akan berjalan di mana saja?

Pada dasarnya apapun itu non-sepele. Jika Anda menulis program non-sepele, Anda akan berakhir secara tidak sengaja tergantung pada cara khusus kompiler yang memesan kelebihan, mencari nama, dan hal-hal rumit lainnya. Lebih lanjut, hampir semua program non-sepele bergantung pada perilaku spesifik platform-non-Standar karena Standar tidak benar-benar memberikan apa pun kecuali beberapa wadah.

Namun, program non-sepele dapat sangat bervariasi dalam hal mudahnya untuk melakukan porting ke platform lain. Jika Anda memprogramnya dengan baik dan mematuhi aturan, Anda dapat dengan mudah porting, dan bonus jika Anda bisa abstrak potongan-potongan ke perpustakaan (yang mungkin sudah disediakan untuk Anda, misalnya Boost.Filesystem).

Program kebanyakan hanya menjadi sangat sulit untuk port antar platform jika mereka melakukan tugas-tugas yang secara inheren platform-spesifik, misalnya, menulis data ke disk dengan jaminan atomicity / konsistensi tertentu, atau, jika Anda bodoh dan berkeliling melakukan hal-hal bodoh yang tidak pernah apa yang seharusnya Anda lakukan di tempat pertama, seperti casting antara int dan pointer.

DeadMG
sumber
2
Tentunya ini melebih-lebihkan kasus ini? Saya tahu bahwa kode C ++ yang lebih esoteris dapat mengalami berbagai bug kompiler dalam kompiler yang lebih tua atau berkualitas lebih rendah, tetapi setiap kompiler yang memenuhi standar harus menangani hal-hal seperti overloading dan pencarian nama yang sama. Pustaka Standar menyediakan I / O, dan (dimulai dengan C ++ 11) threading, dan dukungan sistem file sedang distandarisasi.
Josh Kelley
@JoshKelley: Pada dasarnya tidak ada apa-apanya dibandingkan dengan apa yang dibutuhkan kebanyakan program. Juga, beberapa kompiler yang sangat umum seperti MSVC menerapkan overloading, SFINAE dan pencarian nama secara berbeda dengan hasil yang dapat diamati.
DeadMG
1

Dalam istilah yang sangat sederhana, apa yang membuat lintas platform program adalah kemampuan Anda untuk mengambil sumber dari satu lingkungan, mengompilasinya di lingkungan lain dan membuat produk jadi berfungsi seperti yang diharapkan.

Dalam istilah yang kurang sederhana, program ini memiliki tumpang tindih penuh antara apa yang diharapkan tersedia oleh program dan apa yang disediakan oleh lingkungan target Anda. Setelah Anda melakukan apa pun yang membuat tumpang tindih kurang dari 100%, seperti menggunakan perpustakaan khusus lingkungan atau fitur bahasa dengan perilaku tidak terdefinisi, Anda telah mengikat program Anda ke lingkungan yang dapat menyediakan fitur yang tidak tumpang tindih.

("Platform" adalah kata yang agak licin. Orang-orang dapat berbicara tentang Windows dan Unix sebagai platform atau Linux, OS X, BSD dan Solaris sebagai platform meskipun mereka semua secara nominal Unix. Aduk menjalankan semua hal di atas dengan berbeda arsitektur perangkat keras dan hal-hal menjadi lebih samar. Karena itu, saya akan mulai menggunakan kata.)

Untungnya, ada standar untuk meringankan masalah ini:

Bahasa. Anda sedang menulis C ++, yang pertama kali distandarisasi oleh ISO pada tahun 1998. Program apa pun yang Anda tulis yang sesuai dengan standar itu dapat dikompilasi dan dijalankan dengan hasil yang diharapkan pada platform apa pun dengan kompiler dan runtime yang sesuai. Tidak ada batasan untuk ukuran atau kecanggihan program selama tidak menyimpang dari standar. Jika suatu program yang terbukti memenuhi standar tidak berjalan seperti yang diharapkan pada platform tertentu, implementasi bahasa pada platform tersebut menjadi tersangka. Banyak bahasa memiliki suite tes yang dirancang dengan cermat yang dapat digunakan untuk memverifikasi kesesuaian.

Java mendapat perhatian khusus karena tidak hanya membakukan suatu bahasa, Java juga membakukan kode objek, yang membuat programnya dapat dijalankan di mana saja tanpa kompilasi ulang. Ini dilakukan dengan mendorong titik kesesuaian ke lapisan tambahan ke mesin virtual platform-disesuaikan (atau bahkan perangkat keras) yang mampu menjalankan kode objek.

Lebah. Panggilan yang Anda buat agar program Anda melakukan hal-hal tertentu dapat distandarisasi juga. Seperti bahasa, API dan pustaka yang mengimplementasikannya dapat diatur untuk berperilaku seperti yang diharapkan oleh penelepon menggunakan implementasi mendasar yang sesuai untuk platform tertentu. Salah satu API tersebut adalah standar POSIX IEEE , yang muncul sebagai cara untuk membendung fragmentasi yang terjadi di Unix selama 1980-an. (Saya ada sekitar waktu itu; aspek itu tidak menyenangkan.) Dengan mendefinisikan panggilan dan perilaku standar, vendor sistem dapat memberikan kepercayaan pelanggan mereka bahwa bermigrasi ke OS mereka tidak akan memerlukan banyak pekerjaan seperti yang terjadi di lalu. POSIX secara luas diadopsi dan masih digunakan secara luas hampir 30 tahun kemudian.

Saya telah melakukan banyak proyek yang dengan patuh berpegang pada standar karena saya tahu mereka harus dijalankan pada berbagai platform. Apa yang saya dapatkan untuk masalah saya adalah kode yang bekerja di mana-mana saya berencana untuk menjalankannya dan mengejutkan saya pada beberapa di mana saya tidak.

Blrfl
sumber
0

Pada dasarnya, ketika Anda 'menyentuh' barang di luar program Anda. Satu kasus khusus (saya tidak berani mengatakan satu-satunya kasus) adalah ketika Anda menggunakan perpustakaan yang terkait dengan sistem operasi. Hal-hal seperti menggunakan memori bersama antara proses dan mencetak hal-hal mewah di konsol. Dalam kasus pertama Anda mengakses sepotong memori yang ditangani oleh sistem operasi, dalam kasus kedua layar juga dikendalikan oleh sistem operasi.

Melakukan GUI bergantung pada OS, tetapi ada pustaka GUI yang dibuat untuk lintas platform, sehingga Anda tidak perlu khawatir tentang hal itu. Setidaknya secara teori.

Sulit untuk membuat sesuatu yang non-sepele menjadi cross-platform. Yang baik baru adalah bahwa jika Anda menggunakan perpustakaan yang tepat dan melakukan pengujian yang tepat tidak terlalu sulit untuk membuat perangkat lunak portabel, setidaknya jika kodenya tidak terlalu besar. Seberapa besar terlalu besar tergantung pada ukuran tim Anda, keahlian pemrograman, dan sebagainya.

cauchy
sumber