2011-10-22 20 views
8

Trong C++, nếu tôi viết một trò chơi đơn giản như pong sử dụng Linux, có thể cùng một mã được biên dịch trên Windows và OSX không? Tôi có thể nói nó sẽ không thể được biên dịch ở đâu?Cách di động IS C++?

+9

phụ thuộc vào thư viện/chức năng bạn sử dụng chính xác và liệu chúng có sẵn cho tất cả nền tảng không ... – Yahia

Trả lời

4

Bạn có thể đọc tiêu chuẩn - nếu một chương trình tôn trọng tiêu chuẩn, nó phải được biên dịch trên tất cả các nền tảng có trình biên dịch tuân thủ chuẩn C++.

Đối với thư viện của bên thứ ba bạn có thể đang sử dụng, tính khả dụng của nền tảng thường được chỉ định trong tài liệu.

Khi GUI được đặt câu hỏi, có các tùy chọn đa nền tảng (chẳng hạn như QT), nhưng bạn có thể tự hỏi mình - tôi có thực sự muốn tính di động khi nói đến giao diện người dùng không? Đôi khi, tốt hơn là có phần nền tảng GUI cụ thể.

+0

Tất nhiên, không có trình biên dịch tuân thủ tiêu chuẩn [đã từng là một, nhưng sau đó tiêu chuẩn đã thay đổi], cộng với vô số hành vi được xác định thực hiện, vì vậy "tôn trọng tiêu chuẩn" chỉ là bước một. –

8

C++ cực kỳ di động và có trình biên dịch có sẵn trên nhiều nền tảng hơn bạn có thể lắc một thanh. Các ngôn ngữ như Java thường được quảng cáo như là một cách ồ ạt trên nền tảng, trớ trêu thay thực tế chúng thường được thực hiện trong C++ hoặc C.

Điều đó bao gồm "tính di động". Nếu bạn thực sự có ý nghĩa, nền tảng chéo là C++, thì không quá nhiều: Tiêu chuẩn C++ chỉ định nghĩa một thư viện IO phù hợp với giao diện điều khiển IO - tức là dựa trên văn bản, vì vậy ngay sau khi bạn muốn phát triển một số loại GUI, bạn sẽ cần sử dụng một khung công tác GUI - và các khung công tác GUI có lịch sử rất cụ thể. Windows có nhiều khung công tác GUI "bản địa" bây giờ - khung công tác C++ có sẵn từ Microsoft vẫn là MFC - kết thúc tốt đẹp API Win32 bản địa là một API C. (WPF và WinForms có sẵn cho CLR C++).

Khung công tác GUI của Apple Mac được gọi là Cocoa và là thư viện khách quan-C, nhưng dễ dàng truy cập Mục tiêu C từ C++ trong môi trường phát triển đó. Trên Linux có các khung công tác GTK + và Qt được chuyển sang Windows và Apple, vì vậy một trong các khung công tác C++ này có thể giải quyết "cách viết ứng dụng GUI trong C++ khi xây dựng và chạy trên windows, apple mac và linux ".

Tất nhiên, rất khó để coi Qt là C++ đúng hơn - Qt xác định đánh dấu đặc biệt cho các tín hiệu và vị trí yêu cầu một bước biên dịch trước khi biên dịch.

+1

Ngay cả văn bản I/O là khó khăn để làm portably nếu bạn cần ký tự không phải ASCII. – dan04

+3

Việc đào tại Java bởi vì nó được thực hiện trong C++ là một cá trích đỏ. Perl, Python và Ruby được viết bằng C, nhưng chúng di động hơn nhiều và C vẫn là một cơn ác mộng để mã hóa nền tảng chéo. – Schwern

+0

Ngoài ra còn có một trình biên dịch cho gậy, mặc dù lắc không phải là nguyên tử và bạn cần phải xem sử dụng bộ nhớ. – ssube

1

Nếu bạn đang nghĩ đến việc chuyển từ Linux sang Windows, sử dụng OPENGL cho phần đồ họa cho phép bạn tự do chạy chương trình của mình trên cả hai hệ điều hành miễn là bạn không sử dụng bất kỳ chức năng cụ thể nào của hệ thống.

12

Bạn có ba trở ngại lớn về tính di động.

Việc đầu tiên và đơn giản nhất là viết mã C++ mà tất cả trình biên dịch đích đều hiểu. Lưu ý: điều này khác với việc ghi vào tiêu chuẩn C++. Vấn đề với "viết cho tiêu chuẩn" bắt đầu với: tiêu chuẩn nào? Bạn có C++98, C++03, C++TR1 or C++11? Đây là tất cả các bản sửa đổi cho C++ và phiên bản mới hơn mà bạn sử dụng các trình biên dịch ít tuân thủ hơn. C++ là rất lớn, và thực tế tốt nhất bạn có thể hy vọng cho là C++ 98 với một số tính năng C++ 03.

Trình biên dịch tất cả thêm tiện ích mở rộng của riêng mình và quá dễ dàng để vô tình sử dụng chúng. Bạn sẽ được khôn ngoan để viết vào tiêu chuẩn và không để tài liệu biên dịch. Một số trình biên dịch có chế độ "nghiêm ngặt", nơi chúng sẽ tắt tất cả các tiện ích mở rộng. Bạn sẽ khôn ngoan để làm phát triển chính trong trình biên dịch có độ chặt chẽ nhất và tuân thủ tiêu chuẩn tốt nhất. gcc có họ cờ -Wstrict để bật cảnh báo nghiêm ngặt. -ansi sẽ xóa các tiện ích xung đột với tiêu chuẩn. -std=c++98 sẽ yêu cầu trình biên dịch làm việc với tiêu chuẩn C++ 98 và loại bỏ các phần mở rộng GNU C++.

Với ý nghĩ đó, để duy trì lành mạnh, bạn phải hạn chế bản thân với một số trình biên dịch. Thậm chí việc viết một thư viện C tương đối đơn giản cho nhiều trình biên dịch cũng rất khó. May mắn thay, cả Linux và OS X đều sử dụng gcc. Windows có Visual C++, nhưng các phiên bản khác nhau giống như một gia đình chơi squabbling hơn là một trình biên dịch duy nhất khi nói đến khả năng tương thích (với tiêu chuẩn lẫn nhau), vì vậy bạn sẽ phải chọn một hoặc hai phiên bản để hỗ trợ. Ngoài ra, bạn có thể sử dụng một trong các môi trường trình biên dịch có nguồn gốc gcc như MinGW.

Tiếp theo là thư viện đồ họa và âm thanh của bạn. Nó không chỉ là nền tảng chéo, nó phải nhìn tốt và nhanh chóng trên tất cả các nền tảng. Những ngày này có rất nhiều khả năng, Simple DirectMedia Layer là một. Bạn sẽ phải chọn mức độ bạn muốn mã. Bạn có muốn kiểm soát chi tiết không? Hay bạn muốn động cơ chăm sóc mọi thứ? There's an existing answer for this vì vậy tôi sẽ không đi vào chi tiết. Hãy chắc chắn để chọn một trong đó là dành riêng cho là nền tảng chéo, không chỉ xảy ra để làm việc. Các lỗi tương thích trong thư viện đồ họa của bạn có thể làm giảm nhanh dự án của bạn.

Cuối cùng, có sự không tương thích đơn giản tồn tại giữa các hệ điều hành. POSIX tuân thủ đã đi một chặng đường dài, và bạn may mắn rằng cả Linux và OS X là Unix dưới mui xe, nhưng Windows sẽ luôn là người đàn ông kỳ lạ. Những thứ có khả năng cắn bạn chủ yếu là phải làm với hệ thống tập tin. Dưới đây là một số ít:

  • Filesystem bố trí
  • file con đường cú pháp (ví dụ: C:. \ Foo \ thanh vs/foo/bar)
  • Mandatory Windows file locking
  • Khác với quyền truy cập file hệ thống
  • mô hình khác nhau của liên lạc giữa các quá trình (ví dụ: bộ chia, bộ nhớ dùng chung, vv ..)
  • Các mô hình phân luồng khác nhau (thư viện đồ họa của bạn nên làm mịn điều này)

Ở đó bạn có nó. Thật là một mớ hỗn độn, huh? Lập trình đa nền tảng là một trạng thái của tâm trí và tuyên bố về mục đích vì nó là một kỹ thuật. Nó đòi hỏi một số cống hiến và thêm thời gian. Có một số điều bạn có thể làm để làm cho quá trình ít vất vả ...

  • Bật tất cả hẹp và cảnh báo và sửa chữa chúng
  • Tắt tất cả các phần mở rộng ngôn ngữ
  • kỳ biên dịch và thử nghiệm trong Windows , không chỉ ở phần cuối
  • Nhận lập trình viên người thích Windows trên dự án
  • Restrict mình là vài trình biên dịch như bạn có thể
  • Chọn một maintaine tốt d, cũng hỗ trợ thư viện đồ họa
  • nền tảng Cô lập mã cụ thể (ví dụ, trong một lớp con)
  • Treat Windows như là một công dân hạng nhất

Điều quan trọng nhất là để làm điều này tất cả từ đầu. Tính di động không phải là thứ mà bạn bẻ khóa ở cuối. Không chỉ mã của bạn, nhưng toàn bộ thiết kế của bạn có thể trở nên không thể di chuyển nếu bạn không cảnh giác.

+4

'Điều tốt đẹp về tiêu chuẩn là bạn có quá nhiều thứ để lựa chọn.' ;-) – Voo

-3

So với C, khả năng di chuyển C++ cực kỳ hạn chế, nếu không hoàn toàn chưa có.Đối với một trong những bạn không thể vô hiệu hóa ngoại lệ (tốt bạn có thể), cho các tiêu chuẩn cụ thể nói đó là hành vi không xác định. Nhiều thiết bị thậm chí không hỗ trợ ngoại lệ. Vì vậy, như vậy, C++ là ZERO di động. Plus nhìn thấy UB, nó obvioulsy một no-go cho zero-fail hệ thống thời gian thực hiệu suất cao, trong đó trường hợp ngoại lệ là điều cấm kỵ - hành vi không xác định không có chỗ trong môi trường zero-fail. Sau đó, có tên mangling mà hầu hết, nếu không phải tất cả, trình biên dịch hoàn toàn khác nhau. Đối với tính di động tốt và ngoại vi tương thích bên ngoài "C" sẽ phải được sử dụng để xuất các ký hiệu, nhưng điều này làm cho bất kỳ và tất cả các thông tin không gian tên hoàn toàn vô hiệu, dẫn đến các biểu tượng trùng lặp. Người ta có thể chọn không sử dụng không gian tên và sử dụng tên biểu tượng duy nhất. Tuy nhiên, một tính năng C++ khác đã bị hủy. Sau đó, có sự phức tạp của ngôn ngữ, mà kết quả trong việc thực hiện khó khăn trong các trình biên dịch khác nhau cho các kiến ​​trúc khác nhau. Do những khó khăn này, tính di động thực sự trở thành một vấn đề. Người ta có thể giải quyết điều này bằng cách có một chuỗi lớn các chỉ thị của trình biên dịch/# ifdefs/macro. Mẫu? Thậm chí không được hỗ trợ bởi hầu hết các trình biên dịch.

Tính di động nào? Bạn có nghĩa là bán di động giữa một vài mục tiêu xây dựng dòng chính như MSVC cho Windows và GCC cho Linux? Ngay cả ở đó, trong phân đoạn MAIN-STREAM đó, tất cả các vấn đề và giới hạn trên tồn tại. Nó làm chậm để thậm chí nghĩ rằng C + + là di động.

+1

Hầu hết các điểm bạn đưa ra không liên quan đến câu hỏi được hỏi: *" Tôi có thể biên dịch mã C++ tương thích trên nền tảng khác không? "* và câu trả lời cho câu hỏi đó bị ** không ** đối với các vấn đề bạn mô tả. Bạn không thể (và sẽ không) vô hiệu hóa các ngoại lệ, bởi vì sau đó nó sẽ không còn là C++ nữa. Tên mangling cũng không phải là vấn đề. Đó là một hợp đồng giữa trình biên dịch và trình liên kết, và họ sẽ đồng ý với bất kỳ chuỗi công cụ cụ thể nào. Thiếu hỗ trợ mẫu? Uhm ... vâng. Đó là thiên niên kỷ cuối cùng. – IInspectable