Tính di động của ngôn ngữ C


10

Làm thế nào chính xác là tính di động của một ngôn ngữ như C được xác định? Tôi đã học được rằng trình biên dịch là cụ thể của ISA. Nếu điều này là đúng, C di động như thế nào? Hoặc có phải chỉ là mã nguồn được viết bằng C là di động chứ không phải là tệp thực thi? Không phải các tệp thực thi của ISA cụ thể cho các ứng dụng ví dụ cho x86 tách biệt với các ứng dụng cho Apple (giả sử Apple sử dụng bộ vi xử lý Motorola / PowerPC)?

Câu trả lời:


26

Có phải chỉ là mã nguồn được viết bằng C là xách tay không phải là tệp thực thi?

Chính xác. Một số người gọi nó là viết một lần, biên dịch ở khắp mọi nơi.

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

Cách khác là viết một lần, chạy khắp nơi. Java là một ví dụ tốt về điều này.

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

Và mặc dù bạn có thể đạt được tính di động đa nền tảng một phần, bạn không bao giờ nên mong đợi mã của mình chạy ở mọi nơi mà không cần sửa đổi.


Mã nguồn C không thể di chuyển đến các trình biên dịch hoặc hệ điều hành khác nhau của ISA mà không có một chút shennanigans ngoại ngữ nào. Những điều đơn giản như kích thước và sự liên kết của các loại tiêu chuẩn không phải là tiêu chuẩn trong C, do đó, phần mềm chuyển đổi sẽ trao đổi dữ liệu với các phiên bản khác của chính nó có thể khá khó khăn. Tham khảo GNU Autoconf / Automake để biết ví dụ (có thể bị che khuất) của các vòng mà các lập trình viên C sẽ nhảy qua để có được tính di động.
Tim Williscroft

3
@TimWilliscroft: Các vấn đề về tính di động thường được gây ra bởi các thư viện không chuẩn và thực tiễn lập trình xấu; và không được gây ra bởi C hoặc các thư viện tiêu chuẩn của nó. Một ví dụ đơn giản sẽ sử dụng tiện ích mở rộng GCC không chuẩn hoặc không thực hiện nối tiếp dữ liệu / xê-ri hóa chính xác cho IO.
Brendan

6

Nó không chỉ là cụ thể của ISA. Ví dụ bạn hỏi:

các ứng dụng cho x86 có tách biệt với các ứng dụng cho apple không?

Vâng, họ là, mặc dù Apple sử dụng phần cứng x86. C nhị phân là kiến ​​trúc hệ điều hành cụ thể.


1
@ Steven314: Nhận xét của bạn là một tiếp tuyến. Nó không liên quan gì đến việc phần cứng có phải là tiêu chuẩn hay không, và mọi thứ liên quan đến thực tế là OS X có định dạng nhị phân (Mach-O) khác với Linux, điển hình là ELF).
mipadi

@Steve: EFI vs BIOS chỉ quan trọng đối với việc khởi động và hệ điều hành bên trong; kiến trúc phần cứng, tập lệnh CPU là như nhau, vì nó giống CPU.
vartec

Nhận xét đã bị xóa, chủ yếu là vì tôi không bao giờ nên đưa điều mac vào vị trí đầu tiên. Tôi đề cập đến ABI (Giao diện nhị phân ứng dụng) và các quy ước cuộc gọi vẫn có thể có liên quan (mục thứ ba để thêm vào "kiến trúc và hệ điều hành"). Chúng không liên quan đến phần cứng, ngoại trừ trong đó ABI có xu hướng được thiết kế cho các kiến ​​trúc cụ thể (ví dụ: các thanh ghi có sẵn), nhưng chúng có liên quan đến tính di động nhị phân. Đây không phải là vấn đề về định dạng tệp - ELF được sử dụng trên Windows và Linux (bởi gcc), nhưng có lẽ bạn không thể lấy tệp đối tượng từ cái này sang cái khác.
Steve314

@vartec bạn nói nhị phân C cũng là hệ điều hành cụ thể, có phải vì bản thân O / S là đặc thù của ISA, do đó, nhị phân C trở thành O / S cụ thể gián tiếp?
KawaiKx

@Saurabh - tất cả các tệp thực thi riêng đều dành riêng cho HĐH, vì HĐH chỉ định định dạng tệp. Ngoài ra, thư viện chuẩn C phải thực hiện nhiều chức năng bằng cách gọi hệ điều hành, vì vậy ngay cả khi định dạng tệp được chuẩn hóa, bản thân mã không thể chạy trên HĐH khác. Đây là tiêu chuẩn cho các ngôn ngữ biên dịch thành mã gốc, trái ngược với một số mã máy ảo như JVM (Máy ảo Java). Có thể biên dịch C cho một máy ảo, nhưng không bao giờ thực hiện mà tôi biết. LLVM đến gần nhất, nhưng được dự định là phần cuối của trình biên dịch - không phải là môi trường biên dịch-một lần-chạy-bất cứ nơi nào.
Steve314

5

Có phải chỉ là mã nguồn được viết bằng C là xách tay không phải là tệp thực thi?

Chính xác. Bạn cần biên dịch lại chương trình C của mình trên mọi nền tảng. Trình biên dịch C tạo mã máy chỉ có thể di động ở một mức độ rất hạn chế, giữa các máy có cùng kiến ​​trúc bộ xử lý / bộ nhớ và hệ điều hành. Đó là lý do tại sao bạn thấy các bản phân phối nhị phân khác nhau của các ứng dụng đa nền tảng (ví dụ: trình duyệt), chẳng hạn như "Linux 64 bit Intel" hoặc "Mac OS X 32 bit PowerPC" (OK, cái cuối cùng chỉ là một minh họa, tôi biết Apple đã chuyển đổi đến Intel vài năm trước :-).


3

Hầu hết các câu hỏi đã được trả lời nhưng tôi muốn thêm vào hơn độ bền là một điều khác mà bạn có thể phải tính đến.

Ví dụ, JAVA có thể được viết một lần và chạy trên bất kỳ nền tảng nào có VM (ngày nay, nó được gọi là "Môi trường thời gian chạy"). Nhưng một lợi thế khác là bạn có thể chạy mã Java 1.1 từ năm 1995 trong máy 2011. Điều này là không thể nếu mã của bạn được biên dịch trên i386 và bạn cố chạy nó trên kiến ​​trúc AMD64.

Bạn cũng nhận được những cải tiến của máy ảo.

Sau đó, tôi sẽ nói rằng, nói chung, đi từ ngôn ngữ di động ít nhất sang ngôn ngữ di động hơn bạn sẽ có: Trình biên dịch, ngôn ngữ được biên dịch ở mức độ thấp như C, sau đó là C ++, sau đó diễn giải các ngôn ngữ chạy trong một máy ảo.

Tôi không thực sự là một người bảo vệ Java, ít nhất là không phải vì ngôn ngữ cũng như cộng đồng, nhưng đó là cách để đi nếu bạn đang tìm kiếm tính di động và giảm hiệu năng ít nhất so với C.


3

Câu trả lời tốt về viết một lần biên dịch bất cứ nơi nào.

Mọi người thích nghĩ về C như một ngôn ngữ di động vì tính phổ biến của nó và khả năng cao trình biên dịch C có sẵn cho các nền tảng mục tiêu trong tương lai. Một yếu tố khác là thư viện tiêu chuẩn giúp thực hiện các tác vụ lập trình phổ biến theo cách độc lập với nền tảng.

Vì vậy, tôi muốn nói tính di động của một ngôn ngữ được xác định bởi:

  1. Mức độ tiêu chuẩn hóa.
  2. Tính khả dụng của trình biên dịch cho các nền tảng / kiến ​​trúc khác nhau.
  3. Độ sâu và chiều rộng của thư viện di động.

Trên thực tế, mặc dù hầu hết mọi ứng dụng C phức tạp sẽ yêu cầu một số công việc để chuyển sang nền tảng mới do phụ thuộc vào phần cứng hoặc hệ điều hành. Quá trình đó được gọi là porting.


3

"Tính di động" có nhiều ý nghĩa. Đối với C, nó có nghĩa như sau:

  • Trình biên dịch đã được triển khai cho C cho nhiều nền tảng phần cứng và hệ điều hành, đó là một Thỏa thuận lớn vào đầu những năm 70;

  • Có một tiêu chuẩn được thống nhất trên toàn ngôn ngữ, trái ngược với mỗi triển khai trình biên dịch nhận ra một biến thể ngôn ngữ hơi khác nhau (một lần nữa, một Thỏa thuận lớn khi C được thiết kế lần đầu tiên, vì có nhiều biến thể của ngôn ngữ như Pascal và BASIC mà không được công nhận trên toàn cầu);

  • Do tiêu chuẩn này, mã tuân thủ sẽ tạo ra cùng một hành vi khi được biên dịch trên các nền tảng khác nhau.

Các mã nguồn là xách tay, nhưng một số nhị phân mới đã được tạo ra cho mỗi mục tiêu.

Tuy nhiên, lưu ý rằng nguồn C hiếm khi di động "tầm thường"; hầu hết các ứng dụng yêu cầu bạn vượt xa những gì được xác định bởi tiêu chuẩn ngôn ngữ, sử dụng các tiện ích mở rộng duy nhất cho một nền tảng cụ thể, vì vậy trong thực tế, mã nguồn không thể di động 100%.

Lưu ý, tuy nhiên, C không để lại khá nhiều cho việc thực hiện. Các kích thước chính xác của các loại dữ liệu khác nhau, hành vi tràn, v.v., đều tùy thuộc vào việc thực hiện; tiêu chuẩn cung cấp các yêu cầu tối thiểu mà việc triển khai phải tuân thủ, nhưng việc thực hiện được tự do vượt quá các giới hạn đó.


0

Dù ISA là gì, C không phải là cụ thể của ISA. Tôi giả sử bạn không đề cập đến khe cắm đã lỗi thời cho thẻ mở rộng PC.

Có các trình biên dịch C tuân thủ tiêu chuẩn cho rất nhiều nền tảng và miễn là bạn sử dụng các tính năng ngôn ngữ được xác định đầy đủ trong mã nguồn của mình, bạn sẽ có thể biên dịch nó trên bất kỳ trình biên dịch C nào cho bất kỳ nền tảng nào.

Tuy nhiên, một điều đáng chú ý là tiêu chuẩn C để lại rất nhiều hành vi của các tính năng khi triển khai được xác định hoặc là hành vi không xác định. Điều này được thực hiện để làm cho ngôn ngữ C thường hữu ích hơn cho lập trình cấp thấp, tránh các trường hợp trong đó một số hành vi được xác định chính xác là không phù hợp với những gì phần cứng hỗ trợ trên một số nền tảng. Tuy nhiên, nó làm cho nó khó hơn một chút để viết chương trình di động.

Ngoài ra, không giống như một số ngôn ngữ, C không được cung cấp với một thư viện khổng lồ thuộc loại mà Java hoặc C # cung cấp. Bạn có thể có được các thư viện rất di động để làm bất cứ điều gì, nhưng bạn phải thực hiện một số công việc để xây dựng chúng và khiến chúng hoạt động cùng nhau.

Tất nhiên, C có một thư viện chuẩn, nhưng phạm vi của nó tương đối hạn chế so với Java, C #, Python, v.v.


4
Kiến trúc tập lệnh ISA = kiến ​​trúc hay còn gọi là kiến ​​trúc phần cứng
vartec
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.