簡體   English   中英

C程序在Windows和Unix OS上跨平台差異

[英]C program cross platform differences on Windows and Unix OS

用Windows和Unix編寫的C有什么區別嗎?
我教C和C ++,但我的一些學生回來說,一些示例程序不能在Unix中運行它們。 Unix對我來說很陌生。 不幸的是沒有任何經驗。 我所知道的就是拼寫它。 如果有任何差異,那么我應該建議我們的部門投資Unix系統,因為目前我們實驗室中沒有Unix系統。 我不希望我的學生覺得他們被拒絕或遠離某些東西。

當您不遵守裸C標准時,通常會出現這種問題,並對可能不正確的環境做出假設。 這些可能包括依賴:

  • 非標准,特定平台包括( <conio.h><windows.h><unistd.h> ,...);
  • 未定義的行為( fflush(stdin) ,正如其他人所報告的那樣,不需要按標准做任何事情 - 它實際上是未定義的行為來調用fflush除輸出流之外的任何東西;通常,較舊的編譯器對違反某些微妙規則更寬容如嚴格別名,所以要小心“聰明”指針技巧);
  • 數據類型大小( short = 16位, int = long = 32位假設並不適用於所有地方 - 例如,64位Linux有64位long );
  • 特別是指針大小( void *並不總是32位,並且不能總是安全地轉換為unsigned long ); 一般來說,你應該注意涉及指針的轉換和比較,你應該總是使用提供的類型來代替“普通” int (特別參見size_tptrdiff_tuintptr_t
  • 數據類型“內部格式”(標准並沒有說float s和double s在IEEE 754中,雖然我從未見過平台做不同的事情);
  • 非標准函數( __beginthread ,MS安全字符串函數;另一方面,POSIX / GNU擴展)
  • 編譯器擴展( __inline__declspec#pragma s,...)以及通常以雙下划線開頭的任何內容(或者在舊的非標准實現中使用單個下划線);
  • 控制台轉義碼(當你嘗試在Windows上運行Unix代碼時,這通常是個問題);
  • 回車格式:在正常的字符串是\\n隨處可見,但在寫入文件時,它\\n對* NIX, \\r\\n在Windows上, \\r上預OSX的Mac電腦; 轉換是由文件流自動處理的,因此在您真正想要寫二進制數據時要小心打開二進制文件,並在想要寫文本時將它們保留為文本模式。

無論如何,一個不在* NIX上編譯的程序示例會有所幫助,我們可以為您提供精確的建議。

關於該計划的詳細信息尚未獲得。 這些學生來自我們之前的批次。 已經要求了。 turbo C是目前正在使用的。

正如評論中所述, 請刪除Turbo C和(如果你使用它)Turbo C ++,現在它們都是歷史記錄,並且與當前的C和C ++標准有許多不兼容性(如果我記得很清楚它們都生成16位可執行文件,甚至不能在x86_64上的64位操作系統上運行)。

有許多免費的,工作的和符合標准的替代方案(Windows上的VC ++ Express,MinGW,Pelles C,CygWin,gcc / g ++是Linux上的事實標准,可與clang相媲美),你只需選擇一個。

語言是相同的,但用於獲取任何特定於平台的任何庫都是不同的。 但是,如果您正在教C(而不是系統編程),您應該能夠輕松編寫可移植代碼。 你沒有這樣做的事實讓我想知道你的培訓材料的質量。

隨MSVC一起提供的標准庫以及與典型Linux或Unix編譯器一起提供的標准庫不同,您可能會遇到兼容性問題。 MSVC和GCC之間也可能存在微小的辯證變異。

在類似unix的環境中測試示例的最簡單方法是在現有的Windows工具包上安裝Cygwin或MSYS。 它們基於GCC和常見的開源庫,其行為更像是unix或linux系統上的C編譯器環境。

  • Cygwin是最“unix like”,基於cygwin.dll ,它是一個仿真層,在本機Win32 API之上模擬unix系統調用。 通常,在Cygwin上編譯的任何內容都很可能在Linux上編譯,因為Cygwin基於gcc和glibc。 但是,在Cygwin上編譯的應用程序無法使用本機Win32 API。

  • MSYS / MinGW32旨在使用GCC生成原生Win32應用程序。 但是,大多數標准GNU和其他OSS庫都可用,因此它的行為更像是unix環境而不是VC。 實際上,如果您正在處理不使用Win32或unix特定API的代碼,它可能比MinGW32和MSVC之間更容易在MinGW32和Linux之間移植。

雖然在您的實驗室中安裝Linux可能是一件有用的事情(如果您無法獲得新服務器的資金,請使用VMWare播放器或其他一些虛擬機管理程序),您可以使用上述任一工具鏈來獲取可能“關閉”的內容足夠'為你的目的。 你可以學習unix作為你的想法,Cygwin和MSYS都會給你一個類似unix的環境,在此期間可以給你一些溫和的介紹。

如果Windows和Unix編譯器都遵循相同的C標准,則C語法必須相同。 我被告知MS編譯器仍然不完全支持C99,雖然Unix編譯器速度很快,所以看起來C89是最低的共同點。

但是在Unix世界中,您通常會使用POSIX系統調用來執行系統操作,例如IPC等.Windows不是POSIX系統,因此它具有不同的API。

這個叫做Ansi C的東西。 只要您編寫純粹的Ansi C代碼,就沒有區別。 然而,這是一個相當學術的假設。

在現實生活中,我從未遇到任何代碼可以從Linux移植到Windows,反之亦然,沒有任何修改。 實際上,這個修改S (絕對是復數)變成了大量的預處理器指令,例如#ifdef WINDOWS ... #endif#ifdef UNIX ... #endif ...甚至更多,如果有一些並行庫,例如OPENMPI。

正如您可能想象的那樣,這與可讀和可調試的代碼完全相反,但這是有效的;-)

此外,你必須考慮已經提到的事情:UTF-8有時會淘汰linux編譯器......

在Windows或* nix下,C編程語言之間應該沒有區別,因為語言是由ISO標准指定的。

C語言本身是從Windows到Unix的可移植版本。 但操作系統的詳細信息不同,有時會侵入您的代碼。

例如,Unix系統通常只使用“\\ n”來分隔文本文件中的行,而大多數Windows工具都希望看到“\\ r \\ n”。 有一些方法可以解決這種差異,讓C運行時為你處理它,但是如果你不了解它們,那么編寫特定於操作系統的C代碼就很容易了。

我可以在虛擬機中運行Unix,並在與學生共享之前使用它來測試代碼。

我認為你現在熟悉unix是至關重要的。

一個很好的方法是使用Knoppix CD。

嘗試使用gc在Linux下編譯程序,當它們不起作用時,跟蹤問題(#include <windows>?)並使其工作。 然后返回到窗口,它可能編譯好了。

通過這種方式,您將發現您的程序變得更清潔,更好的教學材料,甚至是在Windows機器上進行實驗練習。

一個常見的問題是fflush(stdin)在Unix上不起作用。 這是完全正常的,因為標准沒有定義實現應該如何處理它。 解決方案是使用這樣的(未經測試):

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

同樣,您需要避免任何導致未定義行為的事情。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM