忍者ブログ

素人翻訳

適当に翻訳する。

ポインタの比較

出典:http://www.velocityreviews.com/forums/t437615-whats-the-help-of-unnecessary-pointer-comparison.html
baumann@pan Guest Posts: n/a 2005年6月4日

皆さんに質問。

「不必要な」ポインタの比較が理解できない。

/*
207 * min()/max() マクロは
208 * 厳格な型の審査をも行う。
209 * 「不必要な」ポインタ比較の項を参照。
210 */
211 #define min(x,y) ({ \
212 typeof(x) _x = (x); \
213 typeof(y) _y = (y); \
214 (void) (&_x == &_y); \
215 _x < _y ? _x : _y; })
216
217 #define max(x,y) ({ \
218 typeof(x) _x = (x); \
219 typeof(y) _y = (y); \
220 (void) (&_x == &_y); \
221 _x > _y ? _x : _y; })
222

214行と220行にはどのような意味があるのか?

両方とも結果は常に「FALSE」になると思っている。というのは、&_x は局所変数 _x の番地(address)であり、&_y は局所変数 _y の番地(address)だから。

だからこの「不必要な」ポインタ比較の意味が分からない。

誰か説明できる人?

baumann@pan

Ben Pfaff Guest Posts: n/a 2005年6月4日

「baumann@pan」の書き込み:

> 「不必要な」ポインタの比較が理解できない。
>
> 211 #define min(x,y) ({ \
> 212 typeof(x) _x = (x); \
> 213 typeof(y) _y = (y); \
> 214 (void) (&_x == &_y); \
> 215 _x < _y ? _x : _y; })

これは gcc 拡張機能を使っている。番地(address)を比較することで、_x と _y が同じ型を持つことを保証するのが214行の狙い。_x と _y が同じ型を持つ場合に限り、それらのポインタも同じ型を持つ。比較の結果は無視されるので、_x と _y が比較不能な型を持っていた場合にコンパイラが診断を始める、というのが唯一の効果。

異なる型の値から生み出された最小値の取得を回避することが目的。なぜなら、そのような最小値を用いると予期せぬ結果が待っているから。例えば次のような宣言があるとする
int x = -1;
unsigned y = 1;
「x > y ? x : y」の値は UINT_MAX である。この種の予期せぬ結果は x と y の両方が int 型なら起こらない。

Ben Pfaff
email:
web: http://benpfaff.org

Keith Thompson Guest Posts: n/a 2005年6月4日

「baumann@pan」の書き込み:

> 「不必要な」ポインタの比較が理解できない。
>
> /*
> 207 * min()/max() マクロは
> 208 * 厳格な型の審査をも行う。
> 209 * 「不必要な」ポインタ比較の項を参照。
> 210 */
> 211 #define min(x,y) ({ \
> 212 typeof(x) _x = (x); \
> 213 typeof(y) _y = (y); \
> 214 (void) (&_x == &_y); \
> 215 _x < _y ? _x : _y; })
> 216
> 217 #define max(x,y) ({ \
> 218 typeof(x) _x = (x); \
> 219 typeof(y) _y = (y); \
> 220 (void) (&_x == &_y); \
> 221 _x > _y ? _x : _y; })
> 222
>
>
> 214行と220行にはどのような意味があるのか?
>
> 両方とも結果は常に「FALSE」になると思っている。というのは、
> &_x は局所変数 _x の番地(address)であり、&_y は局所変数 _y の番地(address)だから。
>
>
> だからこの「不必要な」ポインタ比較の意味が分からない。
>

しかし、どちらのマクロも移植性が極端に低い。typeof() 演算子と文の表現は共に gcc 拡張機能であり、標準 C には含まれていない。

<OT>
typeof() という名前からも分かるように、_x は x と同じ型を持ち、_y は y と同じ型を持つ。_x と _y の番地(address)比較は、これらが同じ型を持つ時は必ず成功し、同じ型を持たない時は成功しない。結果は関係なく、捨てられる。重要なのは、引数の型が一致しなかった場合にコンパイラがマクロ呼び出しを拒絶するようにしていること。
</OT>

Keith Thompson (The_Other_Keith) kst- <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.

Christian Bau Guest Posts: n/a 2005年7月4日

< .com> の記事における
「baumann@pan」 <> の書き込み:

> 皆さんに質問。
>
> 「不必要な」ポインタの比較が理解できない。
>
> /*
> 207 * min()/max() マクロは
> 208 * 厳格な型の審査をも行う。
> 209 * 「不必要な」ポインタ比較の項を参照。
> 210 */
> 211 #define min(x,y) ({ \
> 212 typeof(x) _x = (x); \
> 213 typeof(y) _y = (y); \
> 214 (void) (&_x == &_y); \
> 215 _x < _y ? _x : _y; })
> 216
> 217 #define max(x,y) ({ \
> 218 typeof(x) _x = (x); \
> 219 typeof(y) _y = (y); \
> 220 (void) (&_x == &_y); \
> 221 _x > _y ? _x : _y; })
> 222
>
>
> 214行と220行にはどのような意味があるのか?
>
> 両方とも結果は常に「FALSE」になると思っている。というのは、
> &_x は局所変数 _x の番地(address)であり、&_y は局所変数 _y の番地(address)だから。
>
>
> だからこの「不必要な」ポインタ比較の意味が分からない。
>
> 誰か説明できる人?

これが C でないという事実はともかく、多分 C と似た言語だろう。

min(2, 4.7f) を試そう。通るか? 動くか?

PR

gtkライブラリ連結問題

出典:http://www.cygwin.com/ml/cygwin-xfree/2005-11/msg00088.html
Laitio Mika (Sysline) 2005年11月18日(金)

下のサイトにある gtk の hello world を構築したい。
http://forge.novell.com/modules/xfmod/cvs/cvsbrowse.php/helloworld/helloworld.tar.gz?tarball=1

環境設定(configure)における命令 PKG_CHECK_MODULES(DEPS, gtk+-2.0 >= 2.2 glib-2.0 >= 2.2) に問題があったので、「./configure」実行前にこの命令を無効にする必要があった。

結果、自分の手で Makefile に必要なライブラリと外部ファイル(include files)を加えることになった。

次のように makefile に外部参照(include)と連結(link)の変更を加えたところ、全て翻訳(compile)できたが、連結に失敗した。

-I /usr/include/gtk-2.0 -I /usr/include/glib-2.0 -I /usr/include/pango-1.0 -I /lib/glib-2.0/include -I /lib/gtk-2.0/include -I /usr/include/atk-1.0

及び

-L/usr/X11R6/lib -lgtk-x11-2.0 -lgdk-x11-2.0 -latk-1.0 -lgdk_pixbuf-2.0 -lpangoxft-1.0 -lXft -lfreetype -lz -lXrender -lXext -l fontconfig -lpangox-1.0 -lX11 -lpango-1.0 -lm -lgobject-2.0 -lgmodule-2.0 -lglib-2.0 -lintl -liconv


エラー文はこの通り。

$ make
make all-recursive
make[1]: Entering directory
`/cygdrive/c/cygwin/home/lamikr/helloworld/module5'
Making all in src
make[2]: Entering directory
`/cygdrive/c/cygwin/home/lamikr/helloworld/module5/src'
gcc -g -O2 -L/usr/X11R6/lib -lgtk-x11-2.0 -lgdk-x11-2.0 -latk-1.0
-lgdk_pixbuf-2.0 -lpangoxft-1.0 -lXft -lfreetype -lz -lXrender -lXext -l
fontconfig -lpangox-1.0 -lX11 -lpango-1.0 -lm -lgobject-2.0 -lgmodule-2.0
-lglib-2.0 -lintl -liconv -o hello.exe main.o
main.o: In function `main':
/cygdrive/c/cygwin/home/lamikr/helloworld/module5/src/main.c:20: undefined
reference to `_gtk_init_abi_check'
/cygdrive/c/cygwin/home/lamikr/helloworld/module5/src/main.c:23: undefined
reference to `_gtk_window_new'
/cygdrive/c/cygwin/home/lamikr/helloworld/module5/src/main.c:26: undefined
reference to `_gtk_container_get_type'
/cygdrive/c/cygwin/home/lamikr/helloworld/module5/src/main.c:26: undefined
reference to `_g_type_check_instance_cast'
/cygdrive/c/cygwin/home/lamikr/helloworld/module5/src/main.c:26: undefined
reference to `_gtk_container_set_border_width'
/cygdrive/c/cygwin/home/lamikr/helloworld/module5/src/main.c:29: undefined
reference to `_gtk_window_get_type'
/cygdrive/c/cygwin/home/lamikr/helloworld/module5/src/main.c:29: undefined
reference to `_g_type_check_instance_cast'
/cygdrive/c/cygwin/home/lamikr/helloworld/module5/src/main.c:29: undefined
reference to `_gtk_window_set_title'
/cygdrive/c/cygwin/home/lamikr/helloworld/module5/src/main.c:32: undefined
reference to `_g_type_check_instance_cast'
/cygdrive/c/cygwin/home/lamikr/helloworld/module5/src/main.c:32: undefined
reference to `_gtk_window_set_default_size'
/cygdrive/c/cygwin/home/lamikr/helloworld/module5/src/main.c:35: undefined
reference to `_gtk_window_set_default_icon_from_file'
/cygdrive/c/cygwin/home/lamikr/helloworld/module5/src/main.c:41: undefined
reference to `_g_type_check_instance_cast'
/cygdrive/c/cygwin/home/lamikr/helloworld/module5/src/main.c:41: undefined
reference to `_g_signal_connect_data'
/cygdrive/c/cygwin/home/lamikr/helloworld/module5/src/main.c:44: undefined
reference to `_gtk_label_new'
/cygdrive/c/cygwin/home/lamikr/helloworld/module5/src/main.c:47: undefined
reference to `_g_type_check_instance_cast'
/cygdrive/c/cygwin/home/lamikr/helloworld/module5/src/main.c:47: undefined
reference to `_gtk_container_add'
/cygdrive/c/cygwin/home/lamikr/helloworld/module5/src/main.c:50: undefined
reference to `_gtk_widget_show_all'
/cygdrive/c/cygwin/home/lamikr/helloworld/module5/src/main.c:53: undefined
reference to `_gtk_main'
main.o: In function `on_destroy':
/cygdrive/c/cygwin/home/lamikr/helloworld/module5/src/main.c:11: undefined
reference to `_gtk_main_quit'
collect2: ld returned 1 exit status
make[2]: *** [hello.exe] Error 1
make[2]: Leaving directory
`/cygdrive/c/cygwin/home/lamikr/helloworld/module5/src'
make[1]: *** [all-recursive] Error 1
make[1]: Leaving directory
`/cygdrive/c/cygwin/home/lamikr/helloworld/module5'
make: *** [all] Error 2
(エラーここまで)

以下の命令をどう変えるべきか、分かる方。
"gcc -g -O2 -L/usr/X11R6/lib -lgtk-x11-2.0 -lgdk-x11-2.0 -latk-1.0 -lgdk_pixbuf-2.0 -lpangoxft-1.0 -lXft -lfreetype -lz -lXrender -lXext -l fontconfig -lpangox-1.0 -lX11 -lpango-1.0 -lm -lgobject-2.0 -lgmodule-2.0 -lglib-2.0 -lintl -liconv -o hello.exe main.o"

Igor Pechtchanski 2005年11月18日(金)

全ての「-l」印の前に「main.o」を移動すればよい。(初心者がよくやる間違い)
参考:
http://cygwin.com/faq/faq.programming.html#faq.programming.linker
29.問:
連結器(linker)が何かが見つからないと文句を言う。
29.答:
よくある失敗は、命令文において、ライブラリを必要としているファイルの前にライブラリ名を書いてしまうこと。
「gcc -lstdc++ hello.cc」は間違い。「gcc hello.cc -lstdc++」が正しい。

(これはオブジェクトファイルの連結にも当てはまる。)

カレンダー

04 2024/05 06
S M T W T F S
1 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31

最新コメント

[08/18 NONAME]
[05/18 NONAME]
[04/09 NONAME]
[03/21 NONAME]
[03/20 NONAME]

最新記事

(05/02)
(03/17)
(11/01)
(07/20)
(05/17)
(04/20)
(03/10)
(03/04)
(02/26)
(02/20)
(01/05)
(08/04)
(05/17)
(10/20)
(07/20)
(04/08)
(04/08)
(03/02)
(10/05)
(12/06)
(09/18)
(07/08)
(04/13)
(04/04)
(04/04)

ブログ内検索

広告

バーコード

広告