• ベストアンサー

#defineの使い方について

http://www.linux.or.jp/JM/html/LDP_man-pages/man3/strdup.3.html の書式のところに #define _GNU_SOURCE という一文があるのですが、これは何をしているのでしょうか。 #defineはマクロを定義するために使用するのは、 知っています。#define _GNU_SOURCEは _GNU_SOURCE のあとに 何も書かれていないのが不自然です。

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

  • ベストアンサー
  • sakusaker7
  • ベストアンサー率62% (800/1280)
回答No.4

strdupはISO規格の標準関数にはありません。ただサポートしているコンパイラは 結構あるとは思いますが。 この例の場合ですが、 #define _GNU_SOURCE してから #include <string.h> することによって、GNU固有の拡張が有効になります。 つまりこの場合は、strdup (と他)の宣言が有効になります。 フリーソフトウェア徹底活用講座(17) http://www.cqpub.co.jp/interface/column/freesoft/2004/200408/0.htm GNU コーディング規約: Writing C http://www.sra.co.jp/wingnut/standards/standards-ja_5.html あたりにちょっとだけ説明があります。 シンボルとして定義されていればいいので、具体的な値に対して 行っていないのでしょう。

otaks
質問者

お礼

全部の回答を見まして、 「GNU固有の拡張が有効にする」ためのものだと判断しました。 2重インクルードを防ぐという目的にも使われることを 知りました。 ご回答いただきました皆様方ありがとうございました。

全文を見る
すると、全ての回答が全文表示されます。

その他の回答 (3)

  • Oh-Orange
  • ベストアンサー率63% (854/1345)
回答No.3

★あっ、#endif の位置が違った。 サンプル: /* ヘッダファイルの頭 */ #if !defined( _MY_HEAD_ ) #define _MY_HEAD_ # include <stdio.h> # include <stdlib.h> # include <string.h> /* 関数のプロトタイプ宣言など (ヘッダの中身を記述) */ #endif /* 2重 include 防止対策 */ /* End of my.h */ ←ヘッダファイルの最後 ・上記の方が良いね。失礼!

全文を見る
すると、全ての回答が全文表示されます。
  • Oh-Orange
  • ベストアンサー率63% (854/1345)
回答No.2

★不自然ではありません。 ・確かに #define はマクロや定数を定義しますが、記号定数の場合は『名前』だけ定義することが  できるのです。これを利用することで include ファイルを2重に取り込まなくて良いという方法が  実現できます。便利です。 ・次のそのサンプルを載せます。 サンプル: /* ヘッダファイルの頭 */ #if !defined( _MY_HEAD_ ) #define _MY_HEAD_ # include <stdio.h> # include <stdlib.h> # include <string.h> #endif /* 2重 include 防止対策 */ /* 関数のプロトタイプ宣言など (ヘッダの中身を記述) */ /* End of my.h */ ←ヘッダファイルの最後 解説: ・自作ヘッダに上記のように『#define _MY_HEAD_』とすると最初にインクルードしたときだけ  include 文で stdio.h、stdlib.h、string.h の3つがインクルードされます。  二度、自作ヘッダをインクルードしても既に『_MY_HEAD_』が定義されているため、条件式の  『#if !defined( _MY_HEAD_ )』から『#endif』までがカット(飛ば)されます。 ・名前だけの定数を #define で定義することで、このような場面で活用できます。  不自然というよりは慣れですかね。→始めてみたのでしょうね。 ・以上。参考に。

全文を見る
すると、全ての回答が全文表示されます。
  • MASA_H
  • ベストアンサー率42% (64/151)
回答No.1

#ifdefには反応するのでそれで十分な場合もあります。

全文を見る
すると、全ての回答が全文表示されます。

関連するQ&A

  • Linuxのperrorのpは何の意味?

    Linuxのperrorのpは何の意味? プログラミングをしていて気になりました。 perror http://www.linux.or.jp/JM/html/LDP_man-pages/man3/perror.3.html

  • ${parameter:-word} と ${parameter:=word} の違い

    bashのパラメータ展開で ${parameter:-word} と ${parameter:=word} の違いが何なのかよく分らないのですが、何が違うのでしょうか? http://www.linux.or.jp/JM/html/GNU_bash/man1/bash.1.html

  • defineで定数が置き換えられない?(C言語)

    #defineについて質問です。 #defineは、ソースコード内にこの文字を見つけたら、コンパイルする前にこの文字をこの定数に置き換えて、というプリプロセッサですよね?だから、printfで#defineで定義した定数を出力する場合で、変換指定が必要ない場合は #include <stdio.h> #define DEF 100 void main(){ printf("#defineで定義された定数はDEFです"); } でもいいと思うんです。ですがこのソースコードは間違いで、実行結果は #defineで定義された定数はDEFです(←置き換えられてない) となってしまします。プリプロセッサだけ実行しても、DEFは100に置き換えられずそのままです。printfで#defineで定義した定数を出力させたい場合は書式指定をしなければなりません。なぜ、このような場合は#defineで定義した定数は置き換えられないのでしょうか?回答よろしくお願いします。

  • Windowsでインターバル・タイマーの値を取得または設定する方法

    Linuxで以下の関数を使えば、指定した時間にシグナルとして 指定した関数を呼ぶことが可能ですが、Windowsでは どのようにしたらよいのでしょうか? OsはWindowsXP32bitです。 参考:http://www.linux.or.jp/JM/html/LDP_man-pages/man2/getitimer.2.html #include <sys/time.h> int getitimer(int which, struct itimerval *value); int setitimer(int which, const struct itimerval *value, struct itimerval *ovalue);

  • difftime()について

    difftime()は、秒数の差を返すものなのに、なんでdouble型を返す仕様になっているのでしょうか? double difftime(time_t time1, time_t time0); 関数 difftime() は時刻 time0 から時刻 time1 までの経過時間を double 型で返す。 2 つの時刻の値はカレンダー時間で指定する。カレンダー時間とは紀元 (協定世界時 (UTC) 1970年1月1日 00:00:00) からの経過秒数である。 http://www.linux.or.jp/JM/html/LDP_man-pages/man3/difftime.3.html

  • int select(int n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout)について

    見当違いな質問かもしれませんがお願いします。 複数のソケットを監視する際にselectを使う場合のことですが、 selectの動作と戻り値について疑問があります。 http://www.linux.or.jp/JM/html/LDP_man-pages/man2/select.2.html ここを参照すると、selectの戻り値は 「更新された 3 つのディスクリプタ集合に含まれているディスクリプタの数 (つまり、 readfds, writefds, exceptfds 中の 1 になっているビットの総数) を返す。」 とあります。 私の中でselectは登録してあるFDのうち、一つでも動きがあれば即座にselectを抜けるもの、という認識です。 この認識だとreadfds,writefdsが引数として与えられているとしても、 どちらかのfd_setのうち、一つでも動きがあればselect文は 抜けてしまうことになります。とすると、戻り値として 「readfds, writefds, exceptfds 中の 1 になっているビットの総数」 は常に1ということになってしまいます。しかし、総数というからには 複数同時に1になることもあるはずです。 私の認識が間違っているとは思うのですが、どう間違っているのかわかりません。 select文の動きについて詳しく教えていただけないでしょうか。 または良いページがあれば教えてください。

  • パケット通信時のIPヘッダの取得方法について

    RedHat Linux9上で、g++3.2を使用して、ソケット通信の プログラムを作成していますが、UDPやTCPパケットを受信した際に 各パケットのIPヘッダを取得したいのですが、どのように行えばよいのでしょうか? RAWソケットを使用すればできるかとも思ったのですが、下記のURLに 「IPPROTO_RAW 経由でのあらゆる IP プロトコルの受信は、 raw ソケットを用いては行えない。」と書かれています。 http://www.linux.or.jp/JM/html/LDP_man-pages/man7/raw.7.html 上記のURLには、下記のようにも書かれていました。 packetソケットを使用しなければ実現できないのでしょうか? もし、そうならばpacketソケットのサンプルがありましたら、 教えていただけないでしょうか。 「IPPROTO_RAW ソケットは送信専用である。もしどうしてもすべての IP パケットを受信したい場合は、 packet(7) ソケットを ETH_P_IP プロトコルで用いること。」

  • FTPにログインできない…

    自宅サーバーを立てていますが、.htaccessファイルをアップしても表示されなかったため、このサイトhttp://www.linux.or.jp/JM/html/vsftpd/man5/vsftpd.conf.5.htmlを参考に以下の一文をvsftpd.confへ追記してみたところ、FTPでログインできなくなってしまいました。 仕方なく、この一文を削除し、Vsftpdをリブートしたのですが、ログインが回復せず、困っています。 どなたがご教授お願いします。 追記した一文 force_dot_files=YES FFFTPに出力されるようになったエラー 500 OOPS: could not open chroot() list file:/etc/vsftpd.chroot_list ログインできません.

  • MMAPのMAP_SHAREDについて

    MMAPのMAP_SHAREDについての質問です。 下記ページのMAP_SHAREDの説明文に「ファイルの実際の更新は msync(2) または munmap() が呼ばれるまで行われないこともある。」とあるのですが、このケースは稀なケースなのでしょうか? また、どれくらいの頻度、発生条件などあるのでしょうか? http://linuxjm.sourceforge.jp/html/LDP_man-pages/man2/mmap.2.html

  • 解凍の仕方

    Linuxのレッドハット7.2を使っているのですが, ネットスケープ7.1をDLしたのですが, ファイル(gzで終っている)を解凍しようと思ったのですが, tarというコマンドを使ったのですが,うまく行かず manコマンドで使い方をみたのですが, 書式の読み方がよくわかりません。ファイル名は netscape-i686-pc-linux-gnu-installer.tar.gz というファイルです どうやった解凍できますでしょうか? 現在使っているネットスケープのバージョンは4.78です. お願いします。