• ベストアンサー

PASCALとFARの意味

struct hostent FAR* PASCAL FAR gethostbyname(const char FAR* name); 等でPASCALやFARという文字列がでてきます。 自分なりに調べたのですが FARは16bit時代の名残でfarの別名、32bitのアドレスを明示的に 指すもの?でしょうか。 PASCALについてはよくわかりませんでした。 どなたかご存知の方、ご教授ください。

質問者が選んだベストアンサー

  • ベストアンサー
  • xcrOSgS2wY
  • ベストアンサー率50% (1006/1985)
回答No.4

FARもPASCALも昔の名残です。 FARは16ビット時代に使われていたもので、たいていはfarというキーワードに#defineされていました。 farというキーワードはポインタに対して指定するもので、farをつけるとポインタのサイズが32ビットになり、DOSの頃は1MBまで、Windows 3.xの頃は16MBまでを参照できるようになるものでした。 ちなみにnearというキーワードもあり、ポインタにnearを指定するとポインタのサイズが16ビットになり、そのポインタでは64KBまでしか参照できませんでした。 またfar/nearを省略したときには自動的にどちらか(コンパイラのコマンドラインオプションによる)が選択されました。 Windowsに限定すると、32ビットプログラムではfar/nearの区別はないので、FARは空文字列に#defineされています。 次にPASCALですが、これはたいていpascalというキーワードに#defineされていました。 pascalというキーワードは、以前PASCALがいまよりもずっと流行っていた頃に、C/C++のプログラムからPASCALのプログラムを呼び出す際に使用するものでした。 こちらもWindowsに限定すると、32ビットプログラムでもこのpascalに相当するキーワードが存在します。PASCALはそのキーワードに#defineされています。(Microsoft Visual C++ .NET 2003の場合、そのキーワードは__stdcallです。)

furyfox
質問者

お礼

ご回答有難うございます。 nearというのもあるのですね。 勉強になります。

その他の回答 (5)

  • ultraCS
  • ベストアンサー率44% (3956/8947)
回答No.6

ほとんどトリビア マイクロソフトは、Windows3.0やOffice95あたりまで、プログラムやシステム記述を、高級言語としては、MS-Pascalでコーディングしていました。 そのため、ライブラリの中にPASCALでコーディングされ、その呼び出し規約で呼ばなければならないものが残っていたためです。 実際には、ほとんどのユーザーがTyrbo Pascalを使っていたため、MS-Pascalを使った者は、特に国内では少ないでしょう。Turbo PascalはDelphiとなって再生しましたが、MS-Pascal(FortranやCobolもあったけど)は、消えてしまいましたね。元々のPascalの仕様にはMSの方が(珍しく)準拠していたのですが。 farに付いては、アドレッシングモードの指定ですが、このほかに、nearやshortがあり、それぞれ、8086の命令に対応しています。また、register intなんてのもありましたね。興味があれば調べてみると面白いかも。 処理系によっては12ビットアドレッシングの指定なんかもあったはずです。

furyfox
質問者

お礼

ご回答ありがとうございます。 詳しい回答、色々と勉強になります。 register int は「独習C」に載っていました。 明示的にレジスタを使用するとき使うようですね。

回答No.5

PASCAL は呼び出し規約 Win16では、2つの呼び出し規約、CとPASCALがあった。 PASCAL は、可変長引数はできないが出来上がったコードが小さくなるというメリットがあった。(メリットは無いと言う意見もあるが・・・) 呼び出し規約とは、関数の引数をどの順にスタックに積むとか、誰がスタックフレームを操作するかを決めたもの。 Win32では、STDCALL が使われている。

furyfox
質問者

お礼

ご回答有難うございます。

  • rinkun
  • ベストアンサー率44% (706/1571)
回答No.3

ついでに。 FARはFARポインタやFARコールを指す。 FARポインタはセグメントとオフセットで示されるfarアドレスを参照するポインタで、FARコールは関数が呼び出し元とは別のセグメントにある場合の関数呼び出し方法である。 どちらも基本的に16bit時代のものだが、32bitCPUもセグメントは使えるのでカーネル内などでは今もFARポインタ(この場合は16bitセグメントと32bitオフセットね)を使っているかもしれない。

  • rinkun
  • ベストアンサー率44% (706/1571)
回答No.2

PASCALは元々は関数呼び出し形式がPASCAL形式(PASCALで書かれた関数を呼び出す)であることを示します。PASCALではCとは引数を積む順が逆など違いがあります。 昔のWindowsはPASCALで書かれていたらしく、API周りではPASCAL指定がよく使われます。 現在はPASCAL指定は意味がないので#defineで空文字に置き換えられているはずです。

furyfox
質問者

お礼

ご回答ありがとうございます。 仰るとおり現在では空白になるようですね。

  • 6dou_rinne
  • ベストアンサー率25% (1361/5264)
回答No.1

PASCALというのはプログラム言語の一種で(一時はやったことがありました)、その方式による呼び出し形式です。

furyfox
質問者

お礼

ご回答ありがとうございました。

関連するQ&A

  • HOSTENT構造体を宣言する必要はないのですか?

    ネットワークプログラミングを勉強しているのですが,ソケットを用いた通信のサンプルで, HOSTENT *lphost として,HOSTENT構造体へのポインタを宣言して, lphost = gethostbyname(ホスト名の文字列); で,サーバーのアドレスをHOSTENT構造体にセットするとあります。 構造体へのポインタを宣言しても,構造体自体の領域は確保されないのではないかと思うのですが,gethostbyname関数が返すポインタは,いったい誰がどこに確保した領域を指しているのか,そしてその領域はいつまで保持されるのか,よく理解できません。構造体そのものを宣言せずに,それへのポインタを宣言し,それに関数の戻り値を代入するというのが,よく理解できないです。どなたか解説していただけると幸いです。

  • c++11での文字列リテラルの特殊化について

    c++11言語でのテンプレート部分特殊化についての質問です。 コメントアウト部分は出力結果です template<class T> struct VT { static const int type = 1;}; template<class T,int N> struct VT< T[N] > { static const int type = 2;}; template<class T,int N> struct VT< const T[N] > { static const int type = 3;}; template<class T> struct VT< T* > { static const int type = 4;}; template<class T> struct VT< const T*const > { static const int type = 5;}; #include<iostream> #include<typeinfo> int main(){ std::cout<<"A:"<< VT< char >::type << std::endl; // A:1 std::cout<<"B:"<< VT< char[10] >::type << std::endl; // B:2 std::cout<<"C:"<< VT< char* >::type << std::endl; // C:4 std::cout<<"D:"<< VT< char const [1] >::type << std::endl; // D:3 std::cout<<"E:"<< VT< decltype("") >::type << std::endl; // E:1 std::cout<<"G:"<< typeid( char const [1] ).name() << std::endl;// G:char const [1] std::cout<<"H:"<< typeid( "" ).name() << std::endl;// H:char const [1] } 型名を直接記述したD,G、文字列リテラルを記述したE,H。 コンパイラ毎の差はあれど、GとHの型名は同じものが表示されます。 ですが、[D:3] [E:1]と値は違い、別の特殊化テンプレートが使われています。 この部分が分かりません。 また、配列リテラル、文字列リテラルに対し部分特殊化テンプレートを宣言する方法などありましたら、ご教示お願いします。

  • C++ 文字列とポインタ、STL::mapについて

    C++でポインタと文字列の受け渡しについて質問です。 MyData::search()は文字列を受け取ってメンバ変数 dict内の ヒットしたデータの グループ(文字列)を返すメンバ関数です。 メンバ変数 dict はSTLのmapを使っています。 void MyData::search( const char* funcbox, const char* result ){ for ( map<const char*, const char*>::iterator itr = dict.begin(); itr != dict.end(); ++itr ){ const char* a_name = itr->first; const char* a_group = itr->second; if ( strstr( a_name, funcbox) ){ result = a_group; return; } } result = NULL; } MyData::dict["yamada"] = "groupA"; const char* res = NULL; MyData::search("yamada", res); cout << " group = " << res << endl; 上のようにアクセスするとメンバ関数内では res == "groupA" となりますが、 関数から出るとresはNULLになってしまいます。 res に関数を抜けた後も消えないアドレスを渡すにはどうすればよいでしょうか?

  • 構造体の変数の値を、動的に取得する方法を教えてください

    C言語で、構造体の変数の値を取得したいのですが、その際、 他の変数に格納してある文字列を元に動的に行いたいのですが、可能でしょうか? イメージとしては、 struct Entry{ char name[20]; char address[80]; char email[40]; }; struct Entry data; strcpy(data.name, "Taro"); strcpy(data.address, "Tokyo"); strcpy(data.email, "taro@taro"); char var_name[20]; strcpy(var_name, "email"); printf("%s", data.var_name); ↑この行の構造体の変数へのアクセス方法が間違っているのはわかっていますが、このような時に「taro@taro」と出力させたいのです。 var_nameの値を「name, address, email」に換える事により「Taro, Tokyo, taro@taro」と出力を切り換えたいと思っています。 普段は他の言語をよく使用しており、そちらではこの手法を時々使っていたのですが、C言語でも出来ないものかと思っております。 よろしくお願いします。

  • 線形リストのコードでどーしても理解できない個所があります。

    線形リストのコードでどーしても理解できない個所があります。 (以下、コード部分) typedef struct __node { char name[20]; char tel[16]; struct __node *next; } Node; typedef struct { Node *head; Node *tail; } List; Node *AllocNode(void) { return ((Node *)calloc(1, sizeof(Node))); } /*--- 新たに生成したノードを先頭へ挿入 ---*/ void InsertNode(List *list, const char *name, const char *tel) { Node *ptr = list->head; list->head = AllocNode(); strcpy(list->head->name, name); strcpy(list->haed->tel, tel); list->head->next = ptr; } /*--- pが指すノードの直前にノードを挿入 ---*/ void PutNodeP(List *list, Node *p, const char *name, const char *tel) { if (p == list->head) InsertNode(list, name, tel); else { Node *temp = AllocNode(); if (p == list->tail) list->tail = temp; else *temp = *p; strcpy(p->name, name); strcpy(p->tel, tel); temp->next = p; } } 上の29行目以降の≪pが指すノードの直前にノードを挿入≫についてです。 if文部分については理解できますが、else文部分について、何をやっているのかわからないです。Cの基本的な部分(ポインタも含めて)については充分に理解しているつもりです。 どなたか御教授頂けないでしょうか。 長々と書いてしまいましたがよろしくお願いします。

  • 文字列扱い方

    構造体の中の配列へ文字列を入れる方法がわからなくてこまっています! #include <stdio.h> struct TEST{     char str[32]; }; int main(){     TEST test;     test.str = "test";     return 0; } このように入力するとconst char [5]' から 'char [32]' に変換できません。と出てしまいます。 何か良い方法がありましたらぜひご教授お願いいたします。

  • 配列のアドレスで配列を作るには?

    文字列の先頭アドレスで、配列を作りたいのですが、どうしたらいいでしょうか。 自分ではこのように考えてみました。 char name1[]={"あいうえお"}; char name2[]={"かきくけこ"}; char name3[]={"さしすせそ"}; char name4[]={"たちつてと"}; int *names[]={ name1, name2, name3, name4 }; これで指定してやるときは*names[1]とかって指定すればいいと思ったのですがうまくいきません・・。 何が間違っているのでしょうか? どなたかよろしくお願いします><

  • c言語プログラミング実行時エラーについて質問です。

    c言語プログラミングを実行しようとすると、 エラーが出て次のようなメッセージが出てしまいました。 「「7行目」で記述エラーを発見しました。「constant expression」を付け忘れています。」 どなたか原因を教えてください。よろしくお願いいたします。 以下が失敗したプログラムです。 #include <stdio.h> int main(int argc, const char * argv[]) { const char FILENAME[] = "/Users/user/Desktop/date3.txt"; const int LEN = 100; char line [LEN]; char name [LEN]; char birth [LEN]; char address [LEN]; FILE *dat; dat = fopen(FILENAME, "r"); if ( dat == NULL ) { printf(" ファイル %s がオープンできません. ", FILENAME); return -1; } while( fgets( line, LEN, dat) != NULL ) { sscanf( line "%s, %s, %s", name ,birth, address ); printf("name = %s, address = %s\n", name, address ); } fclose(dat); return 0; }

  • C++の関数テンプレートで分からないところがあります。

    C++の関数テンプレートで分からないところがあります。 C++の入門書を読んで勉強しているのですが、その演習問題(答えはついてないです)で、以下のような問題がありました。 ----------------------------------------------------- 配列の全要素の最小値を求める関数テンプレートを作成せよ。 teplate <class Type> Type minof(const Type x[], int n); という形で作ること。 なお、最も小さい文字列を求められるようにするために、const char *型に明示的に特殊化したものも合わせて作成すること。 ------------------------------------------------ という問題なのですが、これにたいして僕は以下のように答えました。ヘッダのインクルードなどは省きます。 template<class Type> Type minof(const Type x[], const int n) {     int min = 0;     for(int i = 1; i < n; i++)         if(x[min] < x[i])             min = i;     return x[min]; } template<> const char* minof<const char *>(const char x[][64], const int n) {     int min = 0;     for(int i = 1; i < n; i++)         if(strcmp(x[min], x[i]) < 0)             min = i;     return x[min]; } int main() {     const int n = 5;     int a[n];     char s[n][64];     for(int i = 0; i < n; i++){         cout << i + 1 << "番目---";         cin >> a[i];     }     cout << "文字列\n";     for(int i = 0; i < n; i++){         cout << i + 1 << "番目---";         cin >> s[i];     }     cout << "整数の最小値---" << minof(a, n) << "です\n";     cout << "文字列の最小値---" << minof<const char *>(s, n) << "です\n"; } これをコンパイルすると、エラーで 明示的な特殊化; 'const char *minof<const char*>(const char [][64],const int)' は関数テンプレートの特殊化ではありません と 'minof' : 1 番目の引数を 'char [5][64]' から 'const char *const []' に変換できません。 とでてしまいます。 色々探してみたのですが、解決できませんでした・・。 特に最初のほうのエラーがよくわかりません。ちゃんと特殊化してる気はするのですが・・。 間違っている箇所の正当を載せていただけるとわかりやすくて、ありがたいです。 よろしくお願いします!

  • プログラミング初心者です

    アドレス帳を作りたいのですが、下のような構造体を名前(friend[i].name)のアルファベット順に並び替えることはできますか? struct person { char name[30]; char tel[30]; char addr[30]; }; main() { ・ ・ while(a=='y') { struct person friend[20]; scanf("%ls",friend[i].name); scanf("%ls",friend[i].tel); scanf("%ls",friend[i].addr); scanf("%s"&a) i=i+1; } ・ ・ } 質問がわかりにくいかもしれませんが、よろしくお願いします。

専門家に質問してみよう