話說目前.NET好像已經進入了3.0的版本,很久之前為了.NET推出的新的語言C#,我一直感覺他有推動上的困難,還有整體.NET架構的難以實踐
看著.NET由1.0的外皮到現在的3.0,看到M$硬推Vista取代XP,不禁讓人想到,M$還真有耐心弄出一個全新的平台阿
.NET面對三個難題,一個是平台的普及性,另外一個就是能夠展現平台特性的語言,最後是有足夠的開發團隊(這是全世界的開發者要接受新平台)
M$用Vista取代XP,從核心開始取代,所以M$一定要用Vista取代XP,所以狂推是一定要的,因為不然建構平台會有相當的麻煩
接著是語言這檔子麻煩事情,不過以M$來說,他是經驗豐富阿,不過要取代C/C++成為開發應用程式的主要語言,也非朝夕之功阿;不過光是展現和C/C++一樣的功能,也不足以取代,C/C++發展至今已經是怪物等級的了
沒關係,我來個Managed Extension或者來個CLR C++,保證用C/C++也可以展現.NET的特色,還可以讓開發者繼續用C/C++,可是也不能太便宜你阿~當然要搞的跟以前VB一樣阿,讓你最後得轉向C#才可以,所以你沒看到那種可讀性很低的特性嗎?雜著兩種語法,你看的習慣?"破壞"規格可是我的專長阿
(沒看到M$另外一個功績嗎?XML ODF,M$的創舉,世界上目前還沒有一個文書處理器可以處理,他規格就完備了,還號稱相容過去的ODF,真是敗給他了自己推的竟然沒做出來,起碼他開始喊的時候可以加到他的M$ Office 2007上去,結果也沒有~搞笑)
最後就是開發團隊,這個容易阿,大家幾乎都是商人阿,我們只要平台不賣、開發工具不賣;請問你們這些開發團隊除了買新的之外,你還有啥選擇?我舊的完全不維護囉~反正你拿我怎樣,對喔~差點忘記跟你說,舊的bug我會繼續找,然後繼續公佈,你看我實在非常負責阿,還幫你找系統bug哩,自己要記得自己寫code去patch喔~免得到時候被hack
最後~最後~最後,筆者還搞不清楚一件事情,為何我需要.NET?為何我需要Vista?沒聽過MPEG4叫我換OS,也沒人說3.5G要換電腦,偏偏M$要換整個平台?why?why?why?
2008年8月2日 星期六
2008年7月17日 星期四
sizeof的陷阱
看到Jserv的blog http://blog.linux.org.tw/~jserv/archives/001876.html
還真的發現程式語言一些細緻的地方,一些我以前注意過,但是不大放在心上
現在竟然連C跟C++都"不同調",讓我想起以前一些錯誤的sizeof用法
一般人習慣用sizeof來求取陣列大小,但是這個也只是適用於靜態陣列,如果是動態配置就不行
比方說
#include〈iostream〉
using namespace std;
int main(void){
int *a=new int[3];
int b[3];
cout 〈〈 sizeof(a) 〈〈 "," 〈〈 sizeof(b) 〈〈 endl;
delete[] a;
return 0;
}
輸出應該是4,12
因為前面的sizeof取到的是指標大小,所以在32bits的OS裡面是4bytes沒有錯,這是一個常見的忽略
還真的發現程式語言一些細緻的地方,一些我以前注意過,但是不大放在心上
現在竟然連C跟C++都"不同調",讓我想起以前一些錯誤的sizeof用法
一般人習慣用sizeof來求取陣列大小,但是這個也只是適用於靜態陣列,如果是動態配置就不行
比方說
#include
using namespace std;
int main(void){
int *a=new int[3];
int b[3];
cout
delete[] a;
return 0;
}
輸出應該是4,12
因為前面的sizeof取到的是指標大小,所以在32bits的OS裡面是4bytes沒有錯,這是一個常見的忽略
2008年6月14日 星期六
2008年6月5日 星期四
三個好用的C語言工具
老實說,覺得Linux有時候code的documents跟comments實在是很少,真的很佩服那些有空去trace code的人,不過現在發現幾個存在已久的工具(自己孤陋寡聞),可以減少負擔
分別就是ctags, cxref, cflow,簡單的功能介紹如下
分別就是ctags, cxref, cflow,簡單的功能介紹如下
- ctags:列表function的定義
- cxref:分析各個symbol使用到的地方
- cflow:分析呼叫次序
2008年6月3日 星期二
系統程式設計
話說以前有專門的課程都叫做系統程式設計,可是卻是兩碼子事情,一個教導你如何把程式語言變成系統上的machine code,另外一個卻是類似一般程式設計
後者卻是初學者容易陷入混亂的地方,目前大多是C語言,因為一開始還是排除不開一般標準的IO處理,這又是一般初學者在學習程式語言的時候最先接觸的地方,他們就開始有一個懷疑:系統程式設計跟一般程式設計不是差不多嗎?還不就是那些IO
接個更是低階IO的部分,使用的如read, write之類的函數,然後使用者可能覺得這根本是拖褲子放屁,多此一舉(我用fread跟fwrite不是用的好好的嗎?),對於一些啥select, dup之類的function背景又不大了然(我想寫書的作者背景的關係,他們認為已經解釋的很明白,其實初學者根本不懂來由),結果這方面他們就不會去深究
以M$或者java初學者,看到linux系統程式設計,他們大概為覺得signal跟process很不能適應吧,因為他們用的是event跟timer,M$系統程式設計另外又有一套,所以一整個混亂,我想這是一般初學者在進入時候最大的"心理障礙"(當然跟背景也有些關連)
學習過後可能就會發現一件事情,那就是系統程式非常的"底層",他是跟系統強烈相關的,你可能無法很順利的無痛移植到另外一個OS,比方說,你可能寫了一個RS232的通訊程式,可是你卻發現windows並不包含unistd.h這個標頭(我還沒試驗過,我是說可能會有這樣的狀況),然後整個程式就要從新開發
我想在踏入kernel之前,系統程式設計是一門不錯的熱身操
後者卻是初學者容易陷入混亂的地方,目前大多是C語言,因為一開始還是排除不開一般標準的IO處理,這又是一般初學者在學習程式語言的時候最先接觸的地方,他們就開始有一個懷疑:系統程式設計跟一般程式設計不是差不多嗎?還不就是那些IO
接個更是低階IO的部分,使用的如read, write之類的函數,然後使用者可能覺得這根本是拖褲子放屁,多此一舉(我用fread跟fwrite不是用的好好的嗎?),對於一些啥select, dup之類的function背景又不大了然(我想寫書的作者背景的關係,他們認為已經解釋的很明白,其實初學者根本不懂來由),結果這方面他們就不會去深究
以M$或者java初學者,看到linux系統程式設計,他們大概為覺得signal跟process很不能適應吧,因為他們用的是event跟timer,M$系統程式設計另外又有一套,所以一整個混亂,我想這是一般初學者在進入時候最大的"心理障礙"(當然跟背景也有些關連)
學習過後可能就會發現一件事情,那就是系統程式非常的"底層",他是跟系統強烈相關的,你可能無法很順利的無痛移植到另外一個OS,比方說,你可能寫了一個RS232的通訊程式,可是你卻發現windows並不包含unistd.h這個標頭(我還沒試驗過,我是說可能會有這樣的狀況),然後整個程式就要從新開發
我想在踏入kernel之前,系統程式設計是一門不錯的熱身操
IPC之pipe
在沒有thread之前process大概是unix底下最重要的執行單位之一,所以很多基於process的溝通方式變的很重要,比方說pipe、share memory跟message box
thread出來之後,就可以單純的使用共用的memory,在thread之間溝通是比較方便(當然有其他問體衍生出來)
由IPC學習,漸漸的感覺到,對於unix like的系統來說,幾乎啥都是被當作file
高階的pipe使用兩個函數
比方說popen("uname -a","r"),可以看到popen回傳的是一個FILE指標,所以一個pipe也被當作了檔案來運作
高階pipe的運作方式是先建立一個shell然後把command執行類似execl的程序來取得資料,這樣一個運作方式其實還蠻消耗資源的
當然不是一定要透過類似command的模式執行,unix提供另外一種方式,直接套用低階的descriptor
可以看到上面放入了兩個低階的file descriptor,可以將任何寫入file_descriptor[1]的資料透過file_descriptor[0]讀取,採用fifo的原理
回傳的value有可能是
EMFILE:已經超過單一process可用的file descriptor個數
ENFILE:已經超過系統可用的file descriptor個數
EFAULT:descriptor是錯的
這常用在fork後的process於parent/child process之間的溝通上
那如果跨越process呢?本身並沒有絕對的關連,那麼怎麼辦?我不知道unix是否有提供及他的模式可以讓process查詢其他process提供哪些介面的方式,所以他有一個named pipe,看到named就表示過去已經存在,也就是你程式在compile time已經決定名稱的pipe,這樣就可以知道如何存取pipe(以為已經有名字了),其實是透過
其中mknod在有些系統並不提供,其實這個函數就是建立了一個臨時的檔案,這樣一來就可以透過這個檔案然操作,有一點要注意的,可能mode會受到umask的影響,比方說umask為0022在乎叫函數的時候使用0777,ls指令出來的結果會是0755
以上的pipe方式可以看的出來unix like的系統的確把各種實體裝置、虛擬裝置都當成檔案,這樣的設計上當然有好有壞囉,好處是幾乎有統一的介面可以操作;壞處是這樣的特色可能在底層的運作上更麻煩,因為並不是每個裝置的特色都可以符合檔案的模式
thread出來之後,就可以單純的使用共用的memory,在thread之間溝通是比較方便(當然有其他問體衍生出來)
由IPC學習,漸漸的感覺到,對於unix like的系統來說,幾乎啥都是被當作file
高階的pipe使用兩個函數
#include 〈stdio.h〉
FILE *popen(const char *command, const char *open_mode)
pclose(FILE *stream_to_close);
FILE *popen(const char *command, const char *open_mode)
pclose(FILE *stream_to_close);
比方說popen("uname -a","r"),可以看到popen回傳的是一個FILE指標,所以一個pipe也被當作了檔案來運作
高階pipe的運作方式是先建立一個shell然後把command執行類似execl的程序來取得資料,這樣一個運作方式其實還蠻消耗資源的
當然不是一定要透過類似command的模式執行,unix提供另外一種方式,直接套用低階的descriptor
#include 〈unistd.h〉
int pipe(int file_descriptor[2]);
int pipe(int file_descriptor[2]);
可以看到上面放入了兩個低階的file descriptor,可以將任何寫入file_descriptor[1]的資料透過file_descriptor[0]讀取,採用fifo的原理
回傳的value有可能是
EMFILE:已經超過單一process可用的file descriptor個數
ENFILE:已經超過系統可用的file descriptor個數
EFAULT:descriptor是錯的
這常用在fork後的process於parent/child process之間的溝通上
那如果跨越process呢?本身並沒有絕對的關連,那麼怎麼辦?我不知道unix是否有提供及他的模式可以讓process查詢其他process提供哪些介面的方式,所以他有一個named pipe,看到named就表示過去已經存在,也就是你程式在compile time已經決定名稱的pipe,這樣就可以知道如何存取pipe(以為已經有名字了),其實是透過
#include 〈sys/types.h〉
#include 〈sys/stat.h〉
int mkfifo(const char *filename,mode_t mode);
int mknod(const char *filename,mode_t mode|S_IFIFO,(dev_t) 0);
#include 〈sys/stat.h〉
int mkfifo(const char *filename,mode_t mode);
int mknod(const char *filename,mode_t mode|S_IFIFO,(dev_t) 0);
其中mknod在有些系統並不提供,其實這個函數就是建立了一個臨時的檔案,這樣一來就可以透過這個檔案然操作,有一點要注意的,可能mode會受到umask的影響,比方說umask為0022在乎叫函數的時候使用0777,ls指令出來的結果會是0755
以上的pipe方式可以看的出來unix like的系統的確把各種實體裝置、虛擬裝置都當成檔案,這樣的設計上當然有好有壞囉,好處是幾乎有統一的介面可以操作;壞處是這樣的特色可能在底層的運作上更麻煩,因為並不是每個裝置的特色都可以符合檔案的模式
訂閱:
文章 (Atom)