C言語の仕様ないし規格をお教え頂きたいのですが、
適当な文字列 s, t があるとき
memcmp ( s, t, 0 ) の値は不定なのでしょうか?
strncmp( s, t, 0 ) はどうでしょうか?
また、このような規定はどう調べたらよいのでしょうか。
と申しますのは、LSI C-86 Ver.3.30 試食版 では、
memcmp ( s, t, 0 ) が 0 を返す場合と 1 を返す場合があるので、
これが仕様かどうか知りたいのです(たとえば以下のプログラム)。
#製品版がどうなっているかも興味がありますが。
/* LSI-C 試食版 memcmp() テストプログラム */
#include <stdio.h>
#include <string.h>
void test_sub(n)
int n ;
{
char s[]="a";
char t[]="a";
putchar('R'); /* ← これの有無により結果が異なる(ことがある)*/
printf(" memcmp=%d\n", memcmp( s, t, 1 * n ) );
}
int main()
{
test_sub(0);
}
/* LSI-C 試食版 memcmp() テストプログラム 終わり*/
MIYASAKA Masaru さんのフォロー記事 (japan.comp.lang.c)
<91s9n1$gff$1...@nn-tk102.ocn.ad.jp> (2000年12月23日) によれば、
フラグの状態により動作が違うのだそうです。
(^v^) (.. )(o^< >^o) よろしくおねがいします☆
(( ))//^ ))(( ))(( ))
= //林 //林 //林 //林 ================================^
http://www5a.biglobe.ne.jp/~espoir/ やねのすずめ // \
"やねのすずめ" <mid...@mtg.biglobe.ne.jp> wrote in message
news:97gfi0$82m$2...@bgsv5906.tk.mesh.ad.jp...
> C言語の仕様ないし規格をお教え頂きたいのですが、
>
> 適当な文字列 s, t があるとき
> memcmp ( s, t, 0 ) の値は不定なのでしょうか?
> strncmp( s, t, 0 ) はどうでしょうか?
>
> また、このような規定はどう調べたらよいのでしょうか。
>
ANSI Cの規格を調べるのでよいのでは。
>
> と申しますのは、LSI C-86 Ver.3.30 試食版 では、
> memcmp ( s, t, 0 ) が 0 を返す場合と 1 を返す場合があるので、
> これが仕様かどうか知りたいのです(たとえば以下のプログラム)。
> #製品版がどうなっているかも興味がありますが。
>
ひとつの関数が引数が同じで使われる条件によって返す値が異なることが,ちょっと
信じ難いのですが。
規格上どうなっているかは,よく知りませんが,常識的に考えると0を返すのではな
いかと思います。(最初の0文字を比較するのだから,どんな2つの文字列でも等し
いと考えるのが相当ではないでしょうか。)
> void test_sub(n)
> int n ;
> {
> char s[]="a";
> char t[]="a";
>
> putchar('R'); /* ← これの有無により結果が異なる(ことがある)*/
> printf(" memcmp=%d\n", memcmp( s, t, 1 * n ) );
> }
上のプログラムで,疑問なのは,K&R式の書式かANSIの書式かということです。
返り値の型を宣言しているから,ANSIかなとも思うし,引数に型を付けていないか
ら,K&Rかとも思うし。で,こんな場合,引数のn とint n は同じものを指している
のかということです。ちょっとよく分りませんが。
--
********************************
< keizi kounoike >
********************************
memcmpが以下のようなコードだと十分にありえますね。
int memcmp(s,d,n)
char *s,*d;
int n;
{
int c;
while(n-- > 0) {
if((c = *s++ - *d++) != 0) return c;
}
return c;
}
--
___ わしは、山吹色のかすてーらが大好きでのぅ
[[o o]] ふぉっふぉっふぉ
'J' 森下 お代官様 MaNMOS 英夫@ステラクラフト
PGP Finger = CD EA D5 A8 AD B2 FE 7D 02 74 87 52 7C B7 39 37
ANSI Cでどういう仕様になっているか、いまちょっと調
べられないのですが、
> と申しますのは、LSI C-86 Ver.3.30 試食版 では、
> memcmp ( s, t, 0 ) が 0 を返す場合と 1 を返す場合があるので、
> これが仕様かどうか知りたいのです(たとえば以下のプログラム)。
LSI C-86 3.30試食版のマニュアルには第3引数がゼロの
ときのふるまいについて記述がありませんね。しかし可
搬性のところにANSIとありますから、ベンダーとしては
ANSI C互換の動作であると考えているのでしょう。
> MIYASAKA Masaru さんのフォロー記事 (japan.comp.lang.c)
> <91s9n1$gff$1...@nn-tk102.ocn.ad.jp> (2000年12月23日) によれば、
> フラグの状態により動作が違うのだそうです。
この記事はすでに記憶の彼方なので、こちらでちょっと
確認してみました。
LSI C-86 3.30試食版のmemcmp()は3つの引数をレジスタ
ーAX、BX、CXにそれぞれ受け取ります。memcmp()本体を
逆アセンブルすると以下のようになっていました。
3078:06F3 51 PUSH CX
3078:06F4 56 PUSH SI
3077:06F5 57 PUSH DI
3078:06F6 1E PUSH DS
3078:06F7 07 POP ES
3078:06F8 8BF0 MOV SI,AX
3078:06FA 8BFB MOV DI,BX
3078:06FC FC CLD
3078:06FD F3 REPZ
3078:06FE A6 CMPSB
3078:06FF B80000 MOV AX,0000
3078:0702 7405 JZ 0709
3078:0704 1BC0 SBB AX,AX
3078:0706 0D0100 OR AX,0001
3078:0709 5F POP DI
3078:070A 5E POP SI
3078:070B 59 POP CX
3078:070C C3 RET
これを見るかぎり、第3引数のCXが0のときはループを回
らないのでフラグがセットされず、MIYASAKA Masaruさ
んのおっしゃるとおり、memcmp()が呼ばれたときのフラ
グレジスターの状態によって0を返したり1を返したりし
そうですね。
> #製品版がどうなっているかも興味がありますが。
製品版も当然同じでしょう。
--
太田純(Junn Ohta) (株)リコー/新横浜事業所
oh...@sdg.mdd.ricoh.co.jp
"Hideo "Sir MaNMOS" Morishita" <man...@stellar.co.jp> wrote in message
news:squ1ysj...@stellar.co.jp...
>
> > ひとつの関数が引数が同じで使われる条件によって返す値が異なることが,
ちょっと
> > 信じ難いのですが。
>
> memcmpが以下のようなコードだと十分にありえますね。
>
> int memcmp(s,d,n)
> char *s,*d;
> int n;
> {
> int c;
> while(n-- > 0) {
> if((c = *s++ - *d++) != 0) return c;
> }
> return c;
> }
なるほど,でもこんな挙動になる関数をわざわざ書く人がいるとしたら,それも同様
に信じ難いことですが。
でも大田さんの記事<97hpcp$iom$1...@ns.src.ricoh.co.jp>によればそれに近い
実装になっているようですね。
たしかに信じがたいが…
In article <97hpsc$3gs$1...@kmsnews.kms.ac.jp> ,
"keizi kounoike" <koun...@kms.ac.jp> writes
>なるほど,でもこんな挙動になる関数をわざわざ書く人がいるとしたら,それも同様
>に信じ難いことですが。
そうかな。「こんな挙動」の定義にもよると思うのだけど、
複雑な関数になるとわりと良くあることだと思います。
未定義出力が入力に依存するみたいなのをなくすのは結構難しい。
経験を積むにつれ、だんだん、自分のコードを信用しなくなって
くる.....
「こんな挙動」検出機って作れるかな?
---
Shinji KONO @ Information Engineering, University of the Ryukyus,
PRESTO, Japan Science and Technology Corporation
河野真治 @ 琉球大学工学部情報工学科,
科学技術振興事業団さきがけ研究21(機能と構成)
<97hpcp$iom$1...@ns.src.ricoh.co.jp>の記事において
oh...@src.ricoh.co.jpさんは書きました。
ohta> > memcmp ( s, t, 0 ) の値は不定なのでしょうか?
ohta> > strncmp( s, t, 0 ) はどうでしょうか?
ohta> ANSI Cでどういう仕様になっているか、いまちょっと調
ohta> べられないのですが、
C99 によると memcmp(m1, m2, n) の Description は
compares the first n characters of the object pointed to by m1 to
the first n characters of the object pointed to by m2.
で Returns は
The memcmp function returns an integer greater than, equal to, or
less than zero, accordingly as the object pointed to by m1 is
greater than, equal to, or less than the object pointed to by m2.
です. これでわかるように, n == 0 のときになにを返すかについて明示
的な記述はありません.
# strncmp も似た記述になってます.
規格に明示されていないのは
1. 書くのを忘れていた
2. 当然 0 を返すものだと思っているので書かなかった
3. 規格ができた時点で既に処理系により異なっていたので書けなかった
のいずれかが原因でしょう.
ohta> LSI C-86 3.30試食版のマニュアルには第3引数がゼロの
ohta> ときのふるまいについて記述がありませんね。しかし可
ohta> 搬性のところにANSIとありますから、ベンダーとしては
ohta> ANSI C互換の動作であると考えているのでしょう。
上記 3 の原因で規格に明示されていないとすれば「ANSI C 互換」と言っ
ても問題ないでしょうねぇ. 納得いかないけど.
--
名古屋大学 工学部 電子工学科 平田研究室
小野 孝男
Takao Ono wrote:
> 1. 書くのを忘れていた
> 2. 当然 0 を返すものだと思っているので書かなかった
これはありえると思いますが、
>
> 3. 規格ができた時点で既に処理系により異なっていたので書けなかった
>
この理由なら、「未定義動作」と記述するであろう気がします。
それに、当時使われていた処理系の動作とは異なる規格が
定められた例もいくつかありますよね?
ANSI-Cって、非常に練られた企画ですから、「書き忘れ」はまずないと思うのですが・・・。
--
cog...@sp.hudson.co.jp
株式会社ハドソン
研究開発本部 研究開発課
熊岡 忍(Kumaoka Shinobu)
Takao Ono wrote:
> C99 によると memcmp(m1, m2, n) の Description は
> compares the first n characters of the object pointed to by m1 to
> the first n characters of the object pointed to by m2.
> で Returns は
> The memcmp function returns an integer greater than, equal to, or
> less than zero, accordingly as the object pointed to by m1 is
> greater than, equal to, or less than the object pointed to by m2.
ところで、この資料、Webかなにかで見ることはできるのでしょうか?
最近、ANSI-Cがどうのこうのという話が多い(^^;ので。
<3A9C804E...@sp.hudson.co.jp>の記事において
cog...@sp.hudson.co.jpさんは書きました。
coguma> > C99 によると...
coguma> ところで、この資料、Webかなにかで見ることはできるのでしょうか?
coguma> 最近、ANSI-Cがどうのこうのという話が多い(^^;ので。
C99 の規格は pdf になった文書として, あるいは製本された本として
ISO から購入することができます.
pdf 版は ISO のトップページ (http://www.iso.ch/) から ISO
Catalogue ⇒ International Standards (ISO webstore) とたどって,
ISO の番号である 9899:1999を検索すれば購入サイトにたどりつくこと
ができます (334スイスフラン).
また, 製本された本は日本規格協会 (http://www.jsa.or.jp/) を通して
購入することができます (たしか 2万円くらいだったはず).
"Junn Ohta" <oh...@src.ricoh.co.jp> wrote in message
news:97hpcp$iom$1...@ns.src.ricoh.co.jp...
> fj.comp.lang.cの記事<97gfi0$82m$2...@bgsv5906.tk.mesh.ad.jp>で
> mid...@mtg.biglobe.ne.jpさんは書きました。
> > memcmp ( s, t, 0 ) の値は不定なのでしょうか?
> > strncmp( s, t, 0 ) はどうでしょうか?
この関数は,どんな場合も0か1しか返さない様に思いますが,小さい場合の負を返
すところはどこになるんでしょうか。(リタ-ン値はAXにセットされるのだと思い
ますが。)
Takao Ono wrote:
> pdf 版は ISO のトップページ (http://www.iso.ch/) から ISO
> Catalogue ⇒ International Standards (ISO webstore) とたどって,
> ISO の番号である 9899:1999を検索すれば購入サイトにたどりつくこと
> ができます (334スイスフラン).
>
> また, 製本された本は日本規格協会 (http://www.jsa.or.jp/) を通して
> 購入することができます (たしか 2万円くらいだったはず).
はああ、そんなにするんですか(;_;)。個人が普通に買う値段ではないですね。
稟議も通らんだろうなあ。
"Shinji KONO" <ko...@ie.u-ryukyu.ac.jp> wrote in message
news:2953.98...@rananim.ie.u-ryukyu.ac.jp...
> 河野 真治@琉球大情報工学です。
>
> そうかな。「こんな挙動」の定義にもよると思うのだけど、
> 複雑な関数になるとわりと良くあることだと思います。
> 未定義出力が入力に依存するみたいなのをなくすのは結構難しい。
>
すいません。素人なもんで,そんな複雑な関数を扱ったことがないので,こんな発想
しかできませんでした。
でも,利用する側からみれば,特殊な関数を除けば,入力が同じなら出力もいつも同
じを期待したいです。でないと,どうやって制御の流れを追えるコ-ドを書いたらい
いのだろうか。
人間みたいなものなら,同じ入力で,毎回違う出力ってことも考えられますが。
> 経験を積むにつれ、だんだん、自分のコードを信用しなくなって
> くる.....
>
経験を積まなくても,自分のコ-ドは信用していませんが。
> 「こんな挙動」検出機って作れるかな?
少なくとも,私には無理です。
>C99 によると memcmp(m1, m2, n) の Description は
7.21.4(C90 では 7.11.4)もお忘れなく、、、と言いたいのですが、
ここには、
>The memcmp function returns an integer greater than, equal to, or
>less than zero, accordingly as the object pointed to by m1 is
>greater than, equal to, or less than the object pointed to by m2.
大きい/小さいとはどのような意味であるかが規定されているだけです
ね。:-(
--
片山@PFU
>> 3. 規格ができた時点で既に処理系により異なっていたので書けなかった
>この理由なら、「未定義動作」と記述するであろう気がします。
0 が n の定義域に含まれないなら、7.1.7 Use of library function
の規定が適用されるので、ここ(7.11.4)に書かれなくても不思議はあ
りません。
0 が定義域に含まれるかは明確ではないと思います。
#含まれないのは不自然な気はしますが、、、
--
片山@PFU
"keizi kounoike" <koun...@kms.ac.jp> writes:
3078:0706がAND AX,0001ならおっしゃる通りですが、
3078:6FFF MOV AX,0
3078:0704 SBB AX,AX
で負ならAXはFFFFに正ならAXは0000になります。
その後OR AX,0001なので負ならFFFF正なら0001が帰ります。
0の場合は3078:0702にてJZ 0709となるのでAXは0000のままreturnします。
>稟議も通らんだろうなあ。
> 研究開発本部 研究開発課
「C 言語の動向と当社の対応方法についての調査研究」とか、、、(^^)
--
片山@PFU
と言えるくらいの変更があります。字の大きさや例の量が違うので単純
な比較はできませんが、219ページから 528ページに増えています。
6. Language だけでも、78ページから 134ページに増えています。
>この関数は,どんな場合も0か1しか返さない様に思いますが,小さい場合の負を返
>すところはどこになるんでしょうか。(リタ-ン値はAXにセットされるのだと思い
>ますが。)
>> 3078:0704 1BC0 SBB AX,AX
AX ← AX - AX - borrow(borrow = CMPSB で負の時 1、非負の時 0)
>> 3078:0706 0D0100 OR AX,0001
AX ← AX | 1
ですね。ところで、CMPSB って符号付き比較ではありませんか?
--
片山@PFU
x86 の CMP 命令は減算を行ってフラグに結果を反映させるだけなので
符号付き/無しの区別は無いと思います。
ただし、件の場合、結果をボローのみに処理しているので符号無しとして
扱われていると思います。
ちなみに元のプログラムも
SUB AX,AX
CLD
REPZ
CMPSB
JZ ...
なら、長さ 0 でも 0 を返せたと思うのでもったいないですね。
# SUB AX,AX で JZ が真になる予定。
# ついでにプログラムもちょっとだけ短いはず
--
石塚 路志人(ISHIZUKA Michishito)
"KATAYAMA Yoshio" <ka...@pfu.co.jp> wrote in message
news:KATE.01Fe...@sims211.trad.pfu.co.jp...
> In article <97i3cr$63a$1...@kmsnews.kms.ac.jp>,
> "keizi kounoike" <koun...@kms.ac.jp> writes:
>
> >この関数は,どんな場合も0か1しか返さない様に思いますが,小さい場合の負
を返
> >すところはどこになるんでしょうか。(リタ-ン値はAXにセットされるのだと
思い
> >ますが。)
>
> >> 3078:0704 1BC0 SBB AX,AX
>
> AX ← AX - AX - borrow(borrow = CMPSB で負の時 1、非負の時 0)
そうか,ボロをひくのか。こりゃ,ボロが出ましたね。
(実を言うと初めは,太田さんこれって本当にmemcmpのコ-ドなんでしょうかと書い
てたのですが,書き直してよかった。)
ANSI-Cでよいなら,
で,STANDARDS INFO のサ-チで ANSI/ISO/IEC 9899-1999 でProgramming
Languages - C が見つかりますが,PDF版(554ペ-ジ)で18ドルでした。
なぜそう思いました?
> > 3078:0704 1BC0 SBB AX,AX
の意味はおわかりでしょうか?
>> ですね。ところで、CMPSB って符号付き比較ではありませんか?
>x86 の CMP 命令は減算を行ってフラグに結果を反映させるだけなので
>符号付き/無しの区別は無いと思います。
ですね。ボケてました。(*^_^*)
>ただし、件の場合、結果をボローのみに処理しているので符号無しとして
>扱われていると思います。
はい。
--
片山@PFU
In article <97hpcp$iom$1...@ns.src.ricoh.co.jp>,
Junn Ohta <oh...@src.ricoh.co.jp> wrote:
>これを見るかぎり、第3引数のCXが0のときはループを回
>らないのでフラグがセットされず、MIYASAKA Masaruさ
>んのおっしゃるとおり、memcmp()が呼ばれたときのフラ
>グレジスターの状態によって0を返したり1を返したりし
>そうですね。
>
>> #製品版がどうなっているかも興味がありますが。
>
>製品版も当然同じでしょう。
3.5 になりますが製品版を持ってます。製品版には source がつ
いているので確認はより容易ですが、確かに太田さんの挙げたのと
全く同じ mnemonic が書かれていますね。
large model 用のコードは多少異なりますが、引数渡しの部分が
異なるだけで根幹部分は全く同じ実装ですので、結果も全く同じに
なります。
一方 strncmp() の方も source を眺めてみたところ、こちらは
事前に文字列長を調べている関係で、repe cmpsb の直前では必ず
ZF=1 になるように実装されていました。
実際、strncmp() の方では引数の文字列や直前の flag 状態に依
存せず、n == 0 の時には常に 0 を返すようです。
まぁ、ANSI 準拠がどうの以前に、LSI-C の実装にはバグが結構
あるので、これは特定用途向けと割り切って使った方が無難だと思
います。
そもそもは組込み用途向けのクロス開発環境なので、そういう用
途では必要ない関数はおざなりにしか実装されていないように思い
ます。
# dup()/dup2() なんて全く使えないのに、bug report 送っても
#なしのつぶてなんだよなー。
--
しらい たかし
LSI C-86 の製品版は、現在 Ver.3.5 になっていますから、
修正されている可能性もあると思います。
以前 japan.comp.lang.c の方にポストした修正版 memcmp を
こっちにも上げておきます。試食版ユーザーの方はお試しください。
---- memcmp.p86 --(cut here)------------------
CGROUP GROUP TEXT
TEXT CSEG
memcmp_::
push cx
push si
push di
push ds
pop es
mov si,ax
mov di,bx
xor ax,ax
cld
repe cmpsb
jz LAB_0001
sbb ax,ax
or ax,0001H
LAB_0001:
pop di
pop si
pop cx
ret
end
------------------(cut here)------------------
---------------------------------
宮坂 賢 (Miyasaka, Masaru)
Asahikawa-City, Hokkaido, Japan
e-mail : alk...@coral.ocn.ne.jp
"Takao Ono" <ta...@hirata.nuee.nagoya-u.ac.jp> wrote in message
news:97hsr0$jau$1...@henry.hirata.nuee.nagoya-u.ac.jp...
> C99 によると memcmp(m1, m2, n) の Description は
(中略)
> です. これでわかるように, n == 0 のときになにを返すかについて明示
> 的な記述はありません.
C99 の場合なら、以下の場所に関連した規定文があります。これを見ると、
memcmp(p, q, 0) は 0 を返すべき、というようなことが読みとれます。
> 7.21 String handling <string.h>
>
> 7.21.1 String function conventions
(cut)
> [#2] Where an argument declared as size_t n specifies the
> length of the array for a function, n can have the value
> zero on a call to that function. Unless explicitly stated
> otherwise in the description of a particular function in
> this subclause, pointer arguments on such a call shall still
> have valid values, as described in 7.1.4. On such a call, a
> function that locates a character finds no occurrence, a
> function that compares two character sequences returns zero,
> and a function that copies characters copies zero
> characters.
私のところには C90 の資料はありませんので、誰か調べてください(^^;。
> なるほど,でもこんな挙動になる関数をわざわざ書く人がいるとしたら,それも同様
> に信じ難いことですが。
strchr を
char *
strchr (const char *s, int c)
{
for (; *s; s++)
if (*s == c)
return s;
return NULL;
}
と書いてしまう人は結構いそうな気がします.
--
Kazuo Fox Dohzono / doh...@hf.rim.or.jp
[12],(6,9),0,0,2
(4/1449/3742)
一般には大変であることは踏まえた上で、お代官様の例示して
下さったコードに対してなら、もちろんegcsは
warning: `c' might be used uninitialized in this function
と警告してくれます。
---
佐渡詩郎 (さど しろう) / e-mail : sa...@smlab.tutkie.tut.ac.jp
"Kazuo Fox Dohzono" <doh...@hf.rim.or.jp> wrote in message
news:97ja3n$1ota$1...@news2.rim.or.jp...
> In article <97hpsc$3gs$1...@kmsnews.kms.ac.jp>
> "keizi kounoike" <koun...@kms.ac.jp> writes:
>
> > なるほど,でもこんな挙動になる関数をわざわざ書く人がいるとしたら,それも
同様
> > に信じ難いことですが。
>
> strchr を
>
> char *
> strchr (const char *s, int c)
> {
> for (; *s; s++)
> if (*s == c)
> return s;
> return NULL;
> }
>
> と書いてしまう人は結構いそうな気がします.
すいません。これは,引数が同じでも,その他の使用環境で返り値が異なるケ-スな
んでしょうか。どこが,その部分に該当するかちょっと分りませんでした。というこ
とで,「こんな挙動になる関数をわざわざ書く人がいるとしたら」は,取り消しま
す。知らずに,作成されるケ-スもしばし起こり得ると。
そうではなくて
cが0の場合は終端の位置を返すべきなのにNULLが返るという事ではないかと思い
ます。
Kazuo Fox Dohzonoさんがどう言う目的でこの例を示したかはわかりませんが。
--
// 沖野 幸治 OKINO Kouji
// E-mail: ok...@core.co.jp
> cが0の場合は終端の位置を返すべきなのにNULLが返るという事ではないかと思い
> ます。
それ以外にも。int c を char にキャストして比較する必要がありますよね。
初出の例では int と char の実装によって結果が変化しますね。
--
山口@福岡 <hy...@mx7.tiki.ne.jp>
"paoneko" <pao...@e-game.co.jp> wrote in message
news:97ih0r$h39$1...@nn-tk102.ocn.ad.jp...
分っていたら,あんなひとりよがりの記事は書かなかった(or 書けない)と思いま
すが。
蛇足になるんですが、この「文字列の終端を示すナル文字は,文字列の一部と
みなす。」(X3010-1993 の 7.11.5.2節より)というのって、例えば linux の
jman では確認できなくて、例えば パーソナルメディアのANSI C 言語大辞典
では確認できるんですよね。
解説書なんかでは、欠落している場合も結構ありそうな気がします。
# あくまで「気がする」程度です。
> はああ、そんなにするんですか(;_;)。個人が普通に買う値段ではないですね。
以前先輩に (最終版ではない) ドラフトが公開されていると教えてもらいまし
た. 多分最終版ドラフトも何処かにあるんじゃないかと思いますけど.
# ドラフトと規格との違いがあるとまた面白いかも.
> > cが0の場合は終端の位置を返すべきなのにNULLが返るという事ではないかと思い
> > ます。
実はコレ, 昔先輩と飲んだときに
「strchr のコードを思い浮かべてご覧」
(考え中)
「で, そいつは第二引数に '\0' を取れる?」
「…あ」
というやりとりがあったのでした.
> それ以外にも。int c を char にキャストして比較する必要がありますよね。
そうです. これもその時やったのです.
The strchr function locates the first occurrence of c
(converted to a char) in the string pointed to by s. The
terminating null character is considered to be part of the
string.
The strchr function returns a pointer to the located character,
or a null pointer if the character does not occur in the
string.
> 解説書なんかでは、欠落している場合も結構ありそうな気がします。
FreeBSD の man にはちゃんと書かれています. BSD 系列の man ってかなりき
ちんと書かれているイメージがあるのは私だけでしょうか.
# 訳の段階で誤りが混入するのはどの世界でもありがち.
伝統の力?
>> # 訳の段階で誤りが混入するのはどの世界でもありがち.
ちなみに、英語の方でも無かったです。
---
佐渡詩郎 (さど しろう) / e-mail : sa...@smlab.tutkie.tut.ac.jp
仕様と動作と解説は、それぞれ人間の力で一致させないと駄目
なんですよね、おそらく。
Shiroh Sado wrote:
> >> # 訳の段階で誤りが混入するのはどの世界でもありがち.
>
> ちなみに、英語の方でも無かったです。
ちなみに、Solaris の man には、明記されてますね(英語だけど)。
でも、これを日本語に訳したときに抜けるとしたら、それを「誤りが混入する」
とは言いたくないなあ。
--
by Kumano Akio mailto:a-k...@ffc.co.jp / HHE0...@nifty.ne.jp
__________________________________________________________________
FFC Limited Tel:042-585-1167 Fax:042-583-0406
日比野といいます。
In the message "Re: [Q] memcmp(), strncmp() の仕様 "
<3A9DE8F0...@ffc.co.jp>
Kumano Akioさん wrote:
Kumano Akio> Shiroh Sado wrote:
Kumano Akio> > >> # 訳の段階で誤りが混入するのはどの世界でもありがち.
Kumano Akio> >
Kumano Akio> > ちなみに、英語の方でも無かったです。
Kumano Akio> ちなみに、Solaris の man には、明記されてますね(英語だけど)。
Kumano Akio> http://docs.sun.com:80/ab2/coll.40.6/REFMAN3A/@Ab2PageView/244429?DwebQuery=strchr&Ab2Lang=ja&Ab2Enc=shift_jis
GNU C Library 2.2.2 の info にも書かれています。
- Function: char * strchr (const char *STRING, int C)
The `strchr' function finds the first occurrence of the character
C (converted to a `char') in the null-terminated string beginning
at STRING. The return value is a pointer to the located
character, or a null pointer if no match was found.
For example,
strchr ("hello, world", 'l')
=> "llo, world"
strchr ("hello, world", '?')
=> NULL
The terminating null character is considered to be part of the
string, so you can use this function get a pointer to the end of a
string by specifying a null character as the value of the C
argument. It would be better (but less portable) to use
`strchrnul' in this case, though.
GNU C Library を採用している Linux の場合は info を見るほうがより新しい情報が
入手できると思います。
"H.Yamaguchi" <hy...@mx7.tiki.ne.jp> wrote in message
news:97karh$r02$1...@nntp-kyusyu.tiki.ne.jp...
> それ以外にも。int c を char にキャストして比較する必要がありますよね。
> 初出の例では int と char の実装によって結果が変化しますね。
K&R に次のような例があるのですが,これも実装によって結果が変化するのでしょう
か。
void squeeze(char[ ], int c)
{
int i, j;
for (i = j = 0; s[i] != '\0'; i++)
if (s[i] != c)
s[j++] = s[i];
s[j] = '\0';
}
また,型変換のところで,
int i;
char c;
i = c;
c = i;
において c の値は不変とありますが,機種依存なのでしょうか。
例えば、char が 8bit、sizeof(int)>1 の処理系で、
c >= 0x80 とした場合、char が signed か unsigned で
結果が変化しますね。(^^;
c >= 0x100 とすると、関数の仕様にもよりますが、
無意味な動作になりますね。
c < 0 の場合も、char の実装に依存しますね。
ただし、この関数の c の入力条件が 0..0x7F
なのだろうと思います。
または、エラー処理を省略している、
と考えても良いでしょう。(--;
strchr の例では、処理系に依存するかどうか、と言うよりも、
規格に char に キャストして比較しろと書いてある、
と言うのが正しい理由でしょうね。(^_^;;;
> また,型変換のところで,
> int i;
> char c;
>
> i = c;
> c = i;
>
> において c の値は不変とありますが,機種依存なのでしょうか。
どちらも整数型で、sizeof(int) >= sizeof(char) であることが
保障されていますし、上の例も保障されていたと思います。(^^;
--
山口@福岡 <hy...@mx7.tiki.ne.jp>
本筋のお話とは、ずれると思うのですが、少し気になったので便乗質問させてください。
やねのすずめさんが投稿されたテストプログラムの実行結果が、不定なのは、関数の仕様
の問題よりも、変数“n”の初期化を行っていないからのように見えるのですが、いかが
でしょうか?
関数内ではstatic変数以外は初期値の保証はされないと記憶しているのですが、グ
ローバルの変数が別扱いかどうかが疑問です。
識者の方のご意見が伺えれば幸いです。
なんとなく、ジェネレーション・ギャップのようなものを感じます...
void test_sub(n)
int n ; ← これをグローバル変数と勘違いされたように思われます。
{
...
}
この int n は、引数の型を表すもので、非常に古い時代の書き方なんです。
今なら
void test_sub(int n)
{
...
}
と書くところですが。
---- Takeshi SHIGIHARA
OFFICE cyg...@zero.ad.jp
HOME cyg...@po.jah.ne.jp , cyg...@tka.att.ne.jp ------------
Shiroh Sado wrote:
> >> FreeBSD の man にはちゃんと書かれています. BSD 系列の man ってかなりき
> >> ちんと書かれているイメージがあるのは私だけでしょうか.
>
> 伝統の力?
どこでだったか忘れましたが,文化の差だと聞いたことがあります.
linuxはGNU文化なので、manの内容は手抜きで、infoのほうを
まじめに書いてるんだとか.
ほんとうかなぁ。。。
> > >> FreeBSD の man にはちゃんと書かれています. BSD 系列の man ってかなりき
> > >> ちんと書かれているイメージがあるのは私だけでしょうか.
> >
> > 伝統の力?
>
> どこでだったか忘れましたが,文化の差だと聞いたことがあります.
> linuxはGNU文化なので、manの内容は手抜きで、infoのほうを
> まじめに書いてるんだとか.
>
> ほんとうかなぁ。。。
Linuxのmanが頼りにならないのは本当です。
section 1のうちGNUのものは、かなり前から「infoの方が詳しくてup-to-date
だよ」と書いてありました。GNU以外のは作者によっていろいろ。
libcがGNU libcでなかったころ、section 3のman pagesは抜けが多かったり古
かったりであまりあてになりませんでした。GNUになってからはちゃんと...
「infoの方が詳しくてup-to-dateだよ」と書いてある(笑)。
さて、困るのは他のセクション(特にsection 2)です。相変わらずあてになら
ん。カーネルのソース読まないとわからんことも多い。
ところで「BSD 系列の man ってかなりきちんと書かれているイメージがある」っ
ていうのは「Linuxと比べて」なんでしょうか???
# だとしたら基準が低い(笑)ような...
前田敦司
In article <3A9E73BC...@tka.att.ne.jp>,
Takeshi SHIGIHARA <cyg...@po.jah.ne.jp> wrote:
>void test_sub(n)
>int n ; ← これをグローバル変数と勘違いされたように思われます。
>{
>...
>}
>この int n は、引数の型を表すもので、非常に古い時代の書き方なんです。
「非常に」なんて言うなぁぁぁぁ。ぐっすし。
可搬性のために未だに traditional style で coding していま
すが、modern type でないと通らない compiler にはまだ出会って
ません。
--
しらい たかし
いや、こりゃ申し訳ない。
自分でも「非常に」とか書いてて悲しくなってたりしたんですけど、
つい、そのままポストしちゃいました。
>>void test_sub(n)
>>int n ; ← これをグローバル変数と勘違いされたように思われます。
>>{
>>この int n は、引数の型を表すもので、非常に古い時代の書き方なんです。
> 「非常に」なんて言うなぁぁぁぁ。ぐっすし。
> 可搬性のために未だに traditional style で coding していま
>すが、modern type でないと通らない compiler にはまだ出会って
>ません。
通らなかったら規格に合致しなくなります。(^^;
C99 でも同様です。
--
片山@PFU
>> 7.21.1 String function conventions
>> [#2] Where an argument declared as size_t n specifies the
有難うございます。まだ C99 は拾い読み状態なので、ここは確認して
いませんでした。(_ _;
>私のところには C90 の資料はありませんので、誰か調べてください(^^;。
第2パラグラフは C99 で追加されました。C90 では n が 0 場合が明
確ではなかったので、追加されたのだと思います。
--
片山@PFU
> ところで「BSD 系列の man ってかなりきちんと書かれているイメージがある」っ
> ていうのは「Linuxと比べて」なんでしょうか???
いや, それは流石に….
DGUX (5.4.?) 辺りもコンパイル出来ない例とか載ってましたし, 細かいミス
なら SunOS 4 にもありました (昔 fj.unix でもそういう話が幾つか出ていま
したよね). cut & paste で間違えたんじゃないかと思うようなのや「プログ
ラマが読むことを期待していないのではないか」と思えるほど非常に事務的な
ものも何処かで見た覚えがありますし.
読み易くて丁寧だと思うのはやっぱり私だけなんでしょうか.
# BSD というブランドイメージ :-) のせい?
非常に古いっていうか…
int
main(argc,argv)
int argc;
char *argv[];
{
if (cond) {
;;
}
else {
;;
}
if (cond)
if (cond)
for (cond) {
;;
}
}
かならずBSDのカーネルはこのスタイルでしたよ?
----------------------------------
豊島 博 - Toyoshima Hiroshi ICQ#:7784625
mailto:hiroshi@t_h_r_o_w.s_p_a_m.lib.bekkoame.ne.jp
自分自身を大切に
void
main(void)
{
.....
}
っす。
> これを見るかぎり、第3引数のCXが0のときはループを回
> らないのでフラグがセットされず、MIYASAKA Masaruさ
> んのおっしゃるとおり、memcmp()が呼ばれたときのフラ
> グレジスターの状態によって0を返したり1を返したりし
> そうですね。
早速 LSI C-86 Ver 3.30c 試食版問題点リストに追加しようとサンプルプログ
ラムを書いてみて気付いたのですが, 第三引数に即値の 0 を渡すと memcmp
呼び出し直前に xor cx,cx が生成されて偶然うまくいくようです. ひょっと
したらこれでテストを通ってしまったのかもしれませんね.
void
foo (void)
{
int a = 0, b = ~a;
memcmp (&a, &b, 1);
printf ("%d\n", memcmp (&a, &a, 0));
memcmp (&a, &b, 1);
printf ("%d\n", memcmp (&a, &a, a));
}
% foo.exe
0
1
%
> void test_sub(n)
> int n ; ← これをグローバル変数と勘違いされたように思われます。
> {
> ...
> }
あ・・・
そうですね、申し訳ありません。
この記述の仕方は、私もやっていたことがあります。完全に勘違いしておりました。
今度からもう少し、熟考してから投稿するようにいたします。
お恥ずかしい・・・
>早速 LSI C-86 Ver 3.30c 試食版問題点リストに追加しようとサンプルプログ
>ラムを書いてみて気付いたのですが, 第三引数に即値の 0 を渡すと memcmp
>呼び出し直前に xor cx,cx が生成されて偶然うまくいくようです.
はい、実は元記事のサンプルプログラムを作っていて気がつきました。
>ひょっとしたらこれでテストを通ってしまったのかもしれませんね.
…ではなくて、
プログラムが思うような動作をしなかったものですから、
どの分岐を実行したかを調べるために
putchar('R'); などの行を入れたのですが、
それだけでうまく動くようになったので、
いったい何が原因なのか、しばらく悩んでしまった…という次第です。
--
(^v^) (.. )(o^< >^o)
(( ))//^ ))(( ))(( ))
= //林 //林 //林 //林 ================================^
http://www5a.biglobe.ne.jp/~espoir/ やねのすずめ // \
[Q]やねのすずめ <97gfi0$82m$2...@bgsv5906.tk.mesh.ad.jp>
------------------------------------------------
(0)LSI C-86 Ver.3.30 試食版 では、
CPUのフラグレジスタの値により、
memcmp ( s, t, 0 ) が 0 を返す場合と 1 を返す場合がある。
(1)これは仕様なのかバグなのか?
(2)memcmp ( s, t, 0 ) や strncmp( s, t, 0 ) は
どのように規定されているか。
(3)このような規定はどう調べたらよいか。
(4)製品版はどうか。
[A] フォロー記事から要点のみ引用します。
本筋と関係ない記事は省いています。
(0)原因については、
Junn Ohta さん <97hpcp$iom$1...@ns.src.ricoh.co.jp>
の記事に説明があります。
(0)
Kazuo Fox Dohzono さん <97ns0t$145j$1...@news2.rim.or.jp>
------------------------------------------------
>早速 LSI C-86 Ver 3.30c 試食版問題点リストに追加しようとサンプルプログ
>ラムを書いてみて気付いたのですが, 第三引数に即値の 0 を渡すと memcmp
>呼び出し直前に xor cx,cx が生成されて偶然うまくいくようです. ひょっと
>したらこれでテストを通ってしまったのかもしれませんね.
(2)
Junn Ohta さん <97hpcp$iom$1...@ns.src.ricoh.co.jp>
------------------------------------------------
>LSI C-86 3.30試食版のマニュアルには
>第3引数がゼロのときのふるまいについて記述がありませんね。
>しかし可搬性のところにANSIとありますから、
>ベンダーとしてはANSI C互換の動作であると考えているのでしょう。
(2)
Takao Ono さん <97hsr0$jau$1...@henry.hirata.nuee.nagoya-u.ac.jp>
------------------------------------------------
>C99 によると memcmp(m1, m2, n) の Description は
>compares the first n characters of the object pointed to by m1 to
>the first n characters of the object pointed to by m2.
>で Returns は
>The memcmp function returns an integer greater than, equal to, or
>less than zero, accordingly as the object pointed to by m1 is
>greater than, equal to, or less than the object pointed to by m2.
>です. これでわかるように, n == 0 のときになにを返すかについて明示
>的な記述はありません.
># strncmp も似た記述になってます.
>
>規格に明示されていないのは
>1. 書くのを忘れていた
>2. 当然 0 を返すものだと思っているので書かなかった
>3. 規格ができた時点で既に処理系により異なっていたので書けなかった
>のいずれかが原因でしょう.
(2)
KATAYAMA Yoshio さん <KATE.01Fe...@sims211.trad.pfu.co.jp>
------------------------------------------------
>0 が n の定義域に含まれないなら、7.1.7 Use of library function
>の規定が適用されるので、ここ(7.11.4)に書かれなくても不思議はあ
>りません。
>
>0 が定義域に含まれるかは明確ではないと思います。
>
>#含まれないのは不自然な気はしますが、、、
(2)
MIYASAKA Masaru さん <97ivrn$gn2$1...@nn-tk105.ocn.ad.jp>
------------------------------------------------
>C99 の場合なら、以下の場所に関連した規定文があります。これを見ると、
>memcmp(p, q, 0) は 0 を返すべき、というようなことが読みとれます。
>
>> 7.21 String handling <string.h>
>>
>> 7.21.1 String function conventions
>(cut)
>> [#2] Where an argument declared as size_t n specifies the
>> length of the array for a function, n can have the value
>> zero on a call to that function. Unless explicitly stated
>> otherwise in the description of a particular function in
>> this subclause, pointer arguments on such a call shall still
>> have valid values, as described in 7.1.4. On such a call, a
>> function that locates a character finds no occurrence, a
>> function that compares two character sequences returns zero,
>> and a function that copies characters copies zero
>> characters.
>
>私のところには C90 の資料はありませんので、誰か調べてください(^^;。
(2)
KATAYAMA Yoshio さん <KATE.01M...@sims211.trad.pfu.co.jp>
------------------------------------------------
>第2パラグラフは C99 で追加されました。C90 では n が 0 場合が明
>確ではなかったので、追加されたのだと思います。
(3)
keizi kounoike さん <97hijc$1h5$1...@kmsnews.kms.ac.jp>
------------------------------------------------
>ANSI Cの規格を調べるのでよいのでは。
(3)
Takao Ono さん <97i2kr$lr5$1...@henry.hirata.nuee.nagoya-u.ac.jp>
------------------------------------------------
>C99 の規格は pdf になった文書として, あるいは製本された本として
>ISO から購入することができます.
>
>pdf 版は ISO のトップページ (http://www.iso.ch/) から ISO
>Catalogue ⇒ International Standards (ISO webstore) とたどって,
>ISO の番号である 9899:1999を検索すれば購入サイトにたどりつくこと
>ができます (334スイスフラン).
>
>また, 製本された本は日本規格協会 (http://www.jsa.or.jp/) を通して
>購入することができます (たしか 2万円くらいだったはず).
[補足]やねのすずめ:
調べてみました。
1スイスフランは約70円です。日本規格協会経由では 26,720円です。
(3)
keizi kounoike さん <97idp2$91g$1...@kmsnews.kms.ac.jp>
------------------------------------------------
>ANSI-Cでよいなら,
>
>http://www.ansi.org/
>
>で,STANDARDS INFO のサ-チで ANSI/ISO/IEC 9899-1999 でProgramming
>Languages - C が見つかりますが,PDF版(554ペ-ジ)で18ドルでした。
(4)
Takashi SHIRAI さん <97ir5c$pq7$1...@nsvn01.zaq.ne.jp>
------------------------------------------------
> 3.5 になりますが製品版を持ってます。製品版には source がつ
>いているので確認はより容易ですが、確かに太田さんの挙げたのと
>全く同じ mnemonic が書かれていますね。
> large model 用のコードは多少異なりますが、引数渡しの部分が
>異なるだけで根幹部分は全く同じ実装ですので、結果も全く同じに
>なります。
>
> 一方 strncmp() の方も source を眺めてみたところ、こちらは
>事前に文字列長を調べている関係で、repe cmpsb の直前では必ず
>ZF=1 になるように実装されていました。
> 実際、strncmp() の方では引数の文字列や直前の flag 状態に依
>存せず、n == 0 の時には常に 0 を返すようです。
>
># dup()/dup2() なんて全く使えないのに、bug report 送っても
>#なしのつぶてなんだよなー。
[対策]
MIYASAKA Masaru さん <97ivrp$gn2$2...@nn-tk105.ocn.ad.jp>
------------------------------------------------
>以前 japan.comp.lang.c の方にポストした修正版 memcmp を
>こっちにも上げておきます。試食版ユーザーの方はお試しください。
(アセンブリ・ソースは、そちらの記事をごらんください)
今のところ、仕様なのかバグなのかは、まだ断定できないようです。
(そうですよね?)
C99 には適合しませんが、
古いコンパイラ(1991年?)ですから、適用外でしょうし。
--
(^v^) (.. )(o^< >^o) 困った問題には違いありませんが…。
> >ひょっとしたらこれでテストを通ってしまったのかもしれませんね.
>
> …ではなくて、
> プログラムが思うような動作をしなかったものですから、
私がここで言った「テスト」はベンダ側のテストです. つまり, 私は memcmp
のこのような挙動はバグではないかと思っています. 確かに「バグではない」
とする意見もわかるんですが….
# VC++ 1.51 ('95?) の memcmp も似たような挙動を示しますね.
C90 の場合は規定文がないわけですから、規格に基づくとバグとは言えないと
思います。いわゆる未定義動作とか、そういうものと同じように考えるのが、
いちばん安全で移植性も良いと思います。要するに、memcmp(p, q, 0) の動作
には頼らないプログラムにするわけです。
if (n != 0)
result = memcmp(p, q, n);
else
result = 0;
というように場合分けするとか...。
---------------------------------
宮坂 賢 (Miyasaka, Masaru)
Asahikawa-City, Hokkaido, Japan
e-mail : alk...@coral.ocn.ne.jp
「え、void main()!?」とか早とちりする奴が出たりして。すいません俺です。
逝ってくる。FreeBSDでは、mainじゃなくて、void mi_startup(void)って名前
ですね。
それはともかく、それから、FreeBSDでは、ANSIスタイルとクラシックスタイル
を吸収するマクロ__P()も最近では奨励されてませんし。もう、
古いと言って良いのでは無いですか?ダメ?