2010-02-19 34 views
9

Có sự khác biệt nào trong C được viết trong Windows và Unix không?
Tôi dạy C cũng như C++ nhưng một số sinh viên của tôi đã trở lại nói rằng một số chương trình mẫu không chạy cho chúng trong Unix. Unix là người ngoài hành tinh đối với tôi. Thật không may không có kinh nghiệm với nó bất cứ điều gì. Tất cả những gì tôi biết là đánh vần nó. Nếu có bất kỳ sự khác biệt nào thì tôi nên tư vấn cho bộ phận của chúng tôi đầu tư vào các hệ thống cho Unix vì hiện tại không có hệ thống Unix nào trong phòng thí nghiệm của chúng tôi. Tôi không muốn học sinh của tôi cảm thấy rằng họ đã bị từ chối hoặc tránh xa điều gì đó.Sự khác biệt nền tảng chương trình C trên Windows và hệ điều hành Unix

+2

Có thể bạn đang thực hiện một số giả định không được đảm bảo đúng theo tiêu chuẩn C, nhưng đúng trong môi trường cửa sổ. Nếu bạn có thể, xin vui lòng gửi một chương trình nhỏ cho thấy hành vi này. Bạn cũng nên đọc tiêu chuẩn C, hoặc bản nháp nếu bạn không có khả năng mua nó: http://www.open-std.org/jtc1/sc22/WG14/www/docs/n1256.pdf (đây là cho C99). –

+5

Không có hệ thống UNIX nào trong phòng thí nghiệm của bạn? Wow. Làm thế nào cứng nó sẽ được thiết lập một vài hộp Linux? –

+0

Một ví dụ đơn giản là '#include '. Tệp đó không tồn tại trong Unix. Có quá nhiều sự khác biệt và danh sách đầy đủ có thể không khả thi. –

Trả lời

15

Loại sự cố thường xuất hiện khi bạn không tuân thủ tiêu chuẩn C trần và đưa ra các giả định về môi trường có thể không đúng. Đây có thể bao gồm sự phụ thuộc vào:

  • chuẩn, nền tảng cụ thể bao gồm (<conio.h>, <windows.h>, <unistd.h>, ...);
  • hành vi không xác định (fflush(stdin), như một người khác được báo cáo, không bắt buộc phải làm bất kỳ điều gì theo tiêu chuẩn - đó là hành vi không xác định để gọi fflush về bất kỳ thứ gì ngoài luồng đầu ra; chẳng hạn như bí danh nghiêm ngặt, vì vậy hãy cẩn thận với thủ thuật con trỏ "thông minh");
  • kích thước loại dữ liệu (short = 16 bit, int = long = Giả thiết 32 bit không giữ ở mọi nơi - ví dụ: 64 bit Linux, có 64 bit long);
  • nói riêng, kích thước con trỏ (void * không phải lúc nào cũng là 32 bit và không thể luôn được truyền an toàn đến unsigned long); nói chung, bạn nên cẩn thận với các chuyển đổi và so sánh có liên quan đến con trỏ và bạn nên luôn sử dụng các loại được cung cấp cho loại công việc đó thay vì "bình thường" int s (xem cụ thể size_t, ptrdiff_t, uintptr_t)
  • kiểu dữ liệu " định dạng bên trong "(tiêu chuẩn không nói rằng float s và double s đang ở IEEE 754, mặc dù tôi chưa bao giờ thấy các nền tảng hoạt động theo cách khác);
  • chức năng không chuẩn (__beginthread, MS dây an toàn các chức năng; ở phía bên kia, POSIX/GNU phần mở rộng)
  • phần mở rộng trình biên dịch (__inline, __declspec, #pragma s, ...) và trong bất cứ điều gì chung mà bắt đầu bằng dấu gạch dưới đôi (hoặc thậm chí chỉ với một dấu gạch dưới, trong các triển khai cũ, không chuẩn);
  • mã thoát của bảng điều khiển (điều này thường là vấn đề khi bạn cố gắng chạy mã Unix trên Windows);
  • định dạng trả về vận chuyển: trong các chuỗi thông thường là \n ở mọi nơi, nhưng khi được ghi trên tệp, nó là \n trên * NIX, \r\n trên Windows, \r trên máy Mac OSX trước; chuyển đổi được xử lý tự động bởi các luồng tệp, vì vậy hãy cẩn thận để mở tệp theo dạng nhị phân khi bạn thực sự muốn ghi dữ liệu nhị phân và để chúng ở chế độ văn bản khi bạn muốn viết văn bản.

Dù sao ví dụ về chương trình không biên dịch trên * NIX sẽ hữu ích, chúng tôi có thể cung cấp cho bạn các đề xuất bổ sung.

Chi tiết về chương trình chưa nhận được. Các sinh viên từ những đợt trước của chúng tôi. Đã yêu cầu nó. turbo C là những gì đang được sử dụng hiện nay.

Như đã nói trong chú thích, hãy thả Turbo C và (nếu bạn sử dụng) Turbo C++, ngày nay chúng là cả hai phần lịch sử và có nhiều không tương thích với tiêu chuẩn C và C++ hiện tại (và nếu tôi nhớ rõ) cả hai đều tạo ra các tệp thực thi 16 bit, thậm chí sẽ không chạy được trên các hệ điều hành 64 bit trên x86_64).

Có rất nhiều lựa chọn thay thế miễn phí, hoạt động và chuẩn (VC++ Express, MinGW, Pelles C, CygWin trên Windows và gcc/g ++ là tiêu chuẩn không thực tế trên Linux, cạnh tranh với clang), bạn chỉ cần phải chọn một.

+1

+1 cho CygWin và gcc/g ++ trên Windows. Họ sẽ cho phép bạn viết tiêu chuẩn c mà sẽ biên dịch trên chỉ là về bất kỳ * nix và Mac OSX. IMO đó là con đường để đi. –

+0

Vấn đề với họ là CygWin cần thời gian chạy của nó, và sau tất cả đó là một lớp tương thích với UNIX, vì vậy tôi sẽ không khuyên bạn nên sử dụng nó cho các dự án gốc. MinGW, ở phía bên kia, xuất ra bản gốc, "bình thường" Windows EXE. Tuy nhiên, ít nhất là khi tôi thử nó, nó dường như tối ưu hơn VC++ và hơn gcc/g ++ trên Linux, và nó không thể sử dụng SDK Platform "bình thường" của Microsoft, và tôi không thích điều này quá nhiều. Vì vậy, tôi sử dụng VC++ trên Windows và g ++/gcc trên Linux; nó cũng hữu ích để biên dịch ứng dụng của bạn với hai trình biên dịch khác nhau, bạn nắm bắt ngay lập tức các vấn đề tôi đã mô tả ở trên. –

+0

Thực ra, Cygwin cho phép bạn tạo ra các tệp thi hành mà không cần thư viện Cygwin, vì vậy nhận xét đó không thực sự hợp lệ. (Từ bộ nhớ, đó là -mingw, -msys hoặc -mno-cygwin hoặc một số tùy chọn khác dọc theo các dòng đó). Tuy nhiên, chính xác, gcc không cần thiết tạo ra kết quả tối ưu như các trình biên dịch khác - gcc, tuy nhiên, được chuyển rất nhiều vào nhiều kiến ​​trúc và nền tảng, đó là một lợi thế đáng kể. – Arafangion

1

Không có sự khác biệt giữa ngôn ngữ lập trình C trong cửa sổ hoặc * nix, vì ngôn ngữ được chỉ định theo tiêu chuẩn ISO.

2

Cú pháp C phải giống nhau nếu cả trình biên dịch Windows và Unix tuân thủ cùng một tiêu chuẩn C. Tôi đã nói rằng MS trình biên dịch vẫn không hỗ trợ đầy đủ C99, mặc dù trình biên dịch Unix đang lên đến tốc độ, vì vậy có vẻ như C89 là một mẫu số chung thấp nhất.

Tuy nhiên trong thế giới Unix, bạn thường sử dụng các hệ thống POSIX để làm các công cụ hệ thống, như IPC, vv Windows không phải là hệ thống POSIX do đó nó có API khác nhau cho nó.

10

Ngôn ngữ giống nhau, nhưng các thư viện được sử dụng để hoàn thành bất kỳ nền tảng cụ thể nào khác nhau. Nhưng nếu bạn đang dạy C (và không phải lập trình hệ thống), bạn sẽ dễ dàng có thể viết mã di động. Thực tế là bạn không làm như vậy làm cho tôi tự hỏi về chất lượng của tài liệu đào tạo của bạn.

0

Sự cố thường gặp là fflush(stdin) không hoạt động trên Unix. Điều này hoàn toàn bình thường vì tiêu chuẩn không xác định cách triển khai nên xử lý nó. Các giải pháp là sử dụng một cái gì đó như thế này (chưa được kiểm tra):

do 
{ 
    int c = getchar(); 
} 
while (c != '\n' && c != EOF); 

Tương tự như vậy, bạn cần phải tránh bất cứ điều gì gây ra hành vi không xác định.

1

Bản thân ngôn ngữ C là di động từ Windows sang Unix. Nhưng các chi tiết của hệ điều hành khác nhau và đôi khi chúng xâm nhập vào mã của bạn.

Ví dụ, các hệ thống Unix thường chỉ sử dụng "\ n" để phân tách các dòng trong một tệp văn bản, trong khi hầu hết các công cụ Windows đều muốn xem "\ r \ n". Có nhiều cách để xử lý sự khác biệt này theo cách có thời gian chạy C để xử lý nó cho bạn nhưng nếu bạn không cẩn thận, bạn biết về chúng, thật dễ dàng để viết mã C cụ thể của hệ điều hành.

Tôi có thể bạn chạy Unix trong Máy ảo và sử dụng nó để kiểm tra mã của bạn trước khi bạn chia sẻ mã đó với sinh viên của bạn.

1

Tôi nghĩ rằng điều quan trọng là bạn đã tự làm quen với unix ngay bây giờ.

Một cách tuyệt vời để làm điều này là bằng một đĩa CD Knoppix.

Cố gắng biên dịch chương trình của bạn dưới Linux bằng gc và khi chúng không hoạt động, hãy theo dõi các sự cố (#include <windows>?) Và làm cho nó hoạt động. Sau đó trở lại cửa sổ, và nó sẽ biên dịch ok.

Bằng cách này, bạn sẽ khám phá các chương trình của mình trở nên rõ ràng hơn và tài liệu giảng dạy tốt hơn, ngay cả đối với các bài tập trong phòng thí nghiệm trên máy tính Windows.

4

Thư viện chuẩn đi kèm với MSVC và những thư viện có trình biên dịch Linux hoặc Unix điển hình đủ khác nhau để bạn có thể gặp phải các vấn đề tương thích. Cũng có thể có các biến thể biện chứng nhỏ giữa MSVC và GCC.

Cách đơn giản nhất để kiểm tra các ví dụ của bạn trong một môi trường giống như Unix là cài đặt Cygwin hoặc MSYS trên bộ Windows hiện có của bạn. Chúng dựa trên GCC và các thư viện mã nguồn mở phổ biến và sẽ hoạt động giống như môi trường trình biên dịch C trên một hệ thống Unix hoặc Unix.

  • Cygwin là 'unix như' nhất, và được dựa trên một cygwin.dll, mà là một lớp thi đua mà giả lập hệ thống unix gọi trên đầu trang của Win32 API bản địa. Nói chung bất cứ điều gì mà sẽ biên dịch trên Cygwin là rất có khả năng biên dịch trên Linux, như Cygwin được dựa trên gcc và glibc. Tuy nhiên, các API Win32 riêng không có sẵn cho các ứng dụng được biên dịch trên Cygwin.

  • MSYS/MinGW32 được thiết kế để sản xuất ứng dụng Win32 gốc bằng GCC. Tuy nhiên, hầu hết các GNU chuẩn và các thư viện OSS khác đều có sẵn, vì vậy nó hoạt động giống như một môi trường Unix hơn VC. Trong thực tế, nếu bạn đang làm việc với mã không sử dụng Win32 hoặc unix API cụ thể, nó có thể sẽ chuyển giữa MinGW32 và Linux dễ dàng hơn so với giữa MinGW32 và MSVC.

Trong khi cài đặt Linux trong phòng thí nghiệm của bạn có thể là một việc hữu ích để thực hiện (Sử dụng trình phát VMWare hoặc một số trình trợ giúp khác) bạn có thể sử dụng một trong các công cụ trên để nhận cái gì đó có lẽ sẽ là 'đủ gần' cho mục đích của bạn. Bạn có thể tìm hiểu unix như có ưa thích của bạn, và cả Cygwin và MSYS sẽ cung cấp cho bạn một môi trường giống như Unix có thể cung cấp cho bạn một chút giới thiệu nhẹ nhàng trong thời gian chờ đợi.

2

Có điều này được gọi là Ansi C. Miễn là bạn mã hoàn toàn Ansi C, sẽ không có sự khác biệt. Tuy nhiên, đây là một giả định khá học thuật.

Trong cuộc sống thực, tôi chưa bao giờ gặp phải bất kỳ mã nào của mình đang được chuyển từ Linux sang Windows và ngược lại mà không có bất kỳ sửa đổi nào. Trên thực tế, sửa đổi này S (chắc chắn số nhiều) hóa thành một loạt các chỉ thị tiền xử lý, chẳng hạn như #ifdef WINDOWS ... #endif#ifdef UNIX ... #endif ... thậm chí nhiều hơn, nếu một số libs song song, chẳng hạn như OPENMPI đã được sử dụng.

Như bạn có thể tưởng tượng, điều này là hoàn toàn trái với mã dễ đọc và debugable, nhưng đó là những gì làm việc ;-)

Bên cạnh đó, bạn có được để xem xét những điều đã đề cập: UTF-8 đôi khi sẽ knock out linux trình biên dịch ...

Các vấn đề liên quan