Re: Initializing arrays (str{,l,n}cpy())
片山@PFUです。
takao@hirata.nuee.nagoya-u.ac.jp (Takao Ono) writes:
> yas> > char src[10] = "abc";
> yas> > char dst[100];
> yas> > size_t n = sizeof(dst);
> yas> > memcpy(dst, src, n);
> yas> char src[10]; のような配列の場合、未定義でアクセスしても、そ
> yas> れだけでは決して bus error になったりはしません。単に前に使っ
> yas> ていたメモリの内容が出てくるだけです。
> a[10] という配列の場合, アドレスとしては a+0〜a+10 が, データとし
> ては a[0]〜a[9] が有効であり, それ以外のアクセスについては
> undefined behavior となっています. 従って
> 現実的には:
> bus error はないかもしれませんが segmentation fault はありえます.
最近の環境(32 ビット空間の hosted environment)では、90 バイトくらい
はみ出しても SIGSEGV は、まず起きないでしょうが、16 ビット空間の頃は危
なかったです。
当時は環境変数が今ほど多くなかったので、90 バイトのオーバーで 0 番地ア
クセス(*)の可能性がありました。PDP-11 のように 64 KB すべてメモリとな
る CPU では、0 番地アクセスでも読み出しなら SIGSEGV は起きませんが、読
み出しだけでも SIGSEGV となる CPU もありました。
*スタックは 0xffff 番地から若いアドレスへ伸びていきます
*スタックの底に環境変数、その上にコマンド引数が積まれます
*その上に *envp や *argv が積まれます
*それらの総和(+α)が 90 バイトに満たないと 0 番地アクセス
> yas> こういう auto 変数の初期化って、C言語の規格として、OK なん
> yas> ですか。昔はだめだったんだけど。gcc が受付けるのは知っています。
> ISO C では全く合法的です.
更に、C99 では初期値が定数式でなくてもよくなっています。
C90:
6.5.7 Initialization
Constraints
...
All the expressions in an initializer for an object that has static
strage duration or in an initializer list for an object that has
aggregate or union type shall be constant expressions.
C99:
6.7.8 Initialization
Constraints
...
All the expressions in an initializer for an object that has static
strage duration shall be constant expressions or string literals.
--
片山@PFU
Fnews-brouse 1.9(20180406) -- by Mizuno, MWE <mwe@ccsf.jp>
GnuPG Key ID = ECC8A735
GnuPG Key fingerprint = 9BE6 B9E9 55A5 A499 CD51 946E 9BDC 7870 ECC8 A735