アカウント名:
パスワード:
その結果定数メモリへの書き込みが発生するのがバグ
組み込みやってるとconst領域はROMに確保されるのが当たり前だったのでconst付シンボルの中身を書き換えてるソース見て何だこりゃ?って思ったっけ。(そのソースをそのまま組み込み機に移植したら動かなくなったのを思い出した)
#それを相性問題で片づけたのはうちの上司#(Windowsプログラマ部隊より立場弱くて、更に「実績のあるソースだからそのまま使え」の通達付きだった)
組み込みで使われがちなbusyboxもこのバグを踏んでいたというのがなんとも
>const領域はROMに確保されるのが当たり前それをリンカに指定するまでが組み込みプログラマの責任セクションて知ってる?(方言でセグメントと言うかもしれん)それにしてもすごい会社だなそこ
ところで、定数が定数であることはだれの責任なんでしょう?
当時とった解決策(既設ソースは変更不可のため)。RAMが無駄に余裕があったので、全セクションをROMに配置したのち起動時にROM領域を全部RAMにコピーしてジャンプする疑似ブートローダーのバイナリ作ってビルド済みライブラリとしてROMイメージにくっつけた。
#要はPC(Windows)と同じくconstも初期値付き変数も、全部RAM上ならいいんでしょ。となった。#後にGPIOの空き端子にジャンパピンが追加され、新旧2種類のROMイメージから起動できるようになった。#当然最初の要求仕様にはない追加仕様で泣きつかれた結果である
>PC(Windows)と同じくMMUがREADONLYにしているんだよw
>Nの社風なんだろうか?
これはぜってーH社じゃない、F社なんかあり得んだろと思って読んでたらほーらやっぱり
それが、できるならまだ恵まれてる。大昔担当した官公庁向けシステムで同様のパターンの時はそれすらRAM不足で不可でした。(後述のT社とは別件)結局、当該ソースにバグ回避用ラッパー(バグ条件に合致したら制御を乗っ取る)や、それでも回避できない部分は、(現場担当者に断って)闇パッチで対応したり。
#当該システムは設置された施設ごと
その会社の調達のルートではNANDなROMが高いとか。
しまった、間違えた。
×NAND○NOR
ははは、俺が参加したNのプロジェクトもRAMが空いててROMの一部をRAMに移動してた。
最近、破綻するプロジェクトのニュースをよく見るので、IT奴隷ばっかりが増えてプログラマーがいなくなったのかと嘆いていましたが、ここのコメントを見る限りプログラマーが健在だと安心しました。というか、皆さん現役ですよね。2000年ごろの話してませんよね。(X68000とかは明らかに90年代だけど)
(X68000とかは明らかに90年代だけど)
80年代やぞ
年取るとね、昔語りばかりするようになるんですよ。あと10年程度ならつい最近とか思っちゃうの。年取るってほんと怖いんだよ。
自分の中じゃあんときのまんまだもんねいまだにテイラー・スウィフトとか聞いて萌え萌えしてるかんなー意図して September [youtube.com] とか避けてる
自分が萌え萌えしたのは、読込みはROMから、そのアドレスに書込むとRAMに書き込むというコメントかな。Z80のR/W端子を思い出して、ああ昔はいろいろできたなぁ。って懐かしくなった。(今もできるだろうが、モジュール化・ワンチップ化されている今では、コストばかりかかって非現実)
本当に組み込みの方?
今回の話は、コンパイラでどの変数をどのセクションに割り当てるかという段階の話でリンカ云々以前の段階です。そして、固定データを格納するセクションに割り当てられていれば、多くの組み込みではROMに割り当てられるというだけです。
>本当に組み込みの方?
おっおぅ、ExcelVBAにシリアルI/OやTCP/IP実装したりする変態的な組み込みの方だぞ。(こうゆう変態的要求仕様を出して来るのはNだけだとは思いたい)セクション切るのはリンカオプションだったが、この辺は開発環境によるのかな(当時使ってたHEWではリンカオプションだった)
const外すのも、#pragma section切るのもNに却下された。今にして思えば、stdio.hあたりをプロジェクト内部にもってそこでセクション切ってゴニョゴニョしたらブートローダーを2段に噛ますようなアクロバットはしなくて済んだかも。
>それをリンカに指定するまでが組み込みプログラマの責任
あまり良くわかっていなくて申し訳ないのですが…。以下のようなものかなと思うのですが、
const int *v = (void *) 0xFFFFE0000;(int *)v = 1;
リンカがどう関係するのでしょうか?
ポインタ経由すればconst付きで宣言した変数の書換だってできますからね。まあROMに書き込見たいときとか値を固定したいときはdefine使えと。
> ポインタ経由すればconst付きで宣言した変数の書換だってできますからね。
それ処理系依存GCC とかだと最適化のオプション次第ですけど普通に使ってれば SegFault です。
処理系依存ではない。書き換えは未定義動作。「any attempt to modify a const object during its lifetime (3.8) results in undefined behavior.」
未定義動作は処理系がどのように実装しても構わないのだから、処理系依存で間違ってないと思うが。
constからdefineに戻れと・・・。それは流石に方向性間違ってませんか・・・。
define undef defineで値を変更できるので定数化にもなりませんし
boot時は、読み出しはROMでも書き出しはRAMに書かれ,ROMをdisableするとその後はRAMから読み出すようになるっていうのはあったような。まぁ、そういうエリアをconst修飾するってことは少ないでしょうけど、ROMのアクセスは遅かったのでROなセクションでもRAMに展開する意義はあった。
X68000がそんな感じだった覚えがあります速度というよりはベクターテーブルを書き換え可能にするためだったかな※ベクターテーブルも含めた先頭から64kbの領域にIOCS(BIOS)をROMとしてマップしてた
constはその領域が定数メモリ(ROM)である事を宣言するものではないのでキャストの結果書き込みが発生しても、それはプログラマが書いた通りの挙動。
例えばBIOS ROMがFlash Memoryだとして、普段は読み出し前提でconstを付けてるけどBIOS更新用の関数内だけはあえて非constにして書き換えを出来るようにしたとしてそれはバグでもなんでもないわけです。
# そんな書き方をしたソースじゃ後でメンテで死ぬ、という話は別問題
未定義動作を踏んでるのでちょっと違う。その場合、コンパイラ・実行環境は、プログラマが書いた通りに実行する義務を負わない。
「そうは言っても実際問題ちゃんと動くことを確かめてから本番環境に突っ込んでるし、その後もちゃんと動いてるからええやろ」みたいな意見もよく見かけるけど、そのプログラムがちゃんと動く事を誰も公式には保証してくれてない状態なので、ある日突然コンパイラを作ってる側の人の気分で挙動が変わるかも知れない。まさにこういう問題が起こっても自業自得としか言えない。
未定義動作である以上、起動後即時リターンコード0で終了するバイナリが生成されても文句は言えない。参考:https://cpplover.blogspot.com/2014/06/old-new-thing.htm鼻悪魔はジョークだけどタイムトラベルは比較的現実のリスクってーのがまたなんとも……
Cで完全に合法的なstrchrってどう実装するんだろう?
メモリーリークしまくりの毎回mallocしっぱなしか関数内部にstatic領域を準備してそこにコピーして返すスレッドアンセーフですかねたぶん作られた当時はスレッドセーフを考慮してなかったろうから後者かな可変長にするなら内部の領域をchar配列ではなく0初期化済みのcharポインターにしてmalloc+reallocでサイズ更新開放はプロセス終了時処理にまかせるとか
規格に対してはそうかもしれないが、道具としてコンパイラを使う方からしてみたら「未定義動作だよ」と警告を出すか、すなおにsegmentation faultになってバグを顕在化できるほうが嬉しくないか?期待以外の結果なのに一見動作しているように見えるというのは害悪だと思うが。
現実には定数を書き換え不可能領域に配置するコンパイラ/リンカはありふれているわけで、仕様としてはどっちにするのか、それとも現状のまま「仕様としては定めない、実装依存」とするのかという話になりそう
「普段はconstだけど限られた特定の場合だけ書き換えたい」なら「書き換えが必要な処理だけ独立した別processとかにしろや」と思う
C++のconstはオブジェクトの定数性を示すものであって、定数ではない(ことにできる)。すくなくともクラスのインスタンスは。(ref. mutable)たとえばキャッシュを内蔵したクラスで使ってるのを見たことがある。
非修飾型へのポインタを修飾型へのポインタにキャストするのは許容されているが、逆は未定義動作だろ
すくなくともC++では未定義ではないな。それ経由で書き込むと未定義。読むのはOK。
C++は知らんが、Cではポインタの型変換について修飾付ける方向のしか規格に記載されていないから、const外しキャストは未定義動作になる。strchrとか標準関数ですらreturn値でconst外してくるあたり、規格自体が狂ってる感はあるけども。
> strchrとか標準関数ですらreturn値でconst外してくるあたり、規格自体が狂ってる感はあるけども。
それはアタナの勘違い
const char * strchr ( const char * str, int character ); char * strchr ( char * str, int character );
プロトタイプ宣言が2つあります
const char * strchr ( const char * str, int character );
char * strchr ( char * str, int character );
Cでそんなことできたっけかな?
int main(void){}
https://wandbox.org/permlink/k4ROmZcUnxTwh7Ab [wandbox.org]
prog.c:2:20: error: conflicting types for 'strchr' 2 | char * strchr ( char * str, int character ); |
X3010の草案(?) [kikakurui.com]だと
7.21.5.2 strchr関数形式 #include char *strchr(const char *s,
それC++のstd::strchrだろ、Cには関係ない。
最初に「C++は知らんが、Cでは」と書かれているのすら見えないバカがいるのか
これはconstやキャストの問題ではなくstrchrの戻り値をconst char*にすべきだったという問題だと思いますね
strchr自体は、strを書き換えないので、引数はconstでいい。戻りは、呼び出し元が書き換えたいニーズもあるので、裸でいい。でないとキャストがいる。書き換えないなら、const char*な変数にでもうければいい。こっちはキャストいらない。
strchrの戻り値がchar *の場合、strchrの内部でconst外しキャストが必要strchrの戻り値がconst char*の場合、呼び出し元で(書き換えたいときは)const外しキャストが必要
どちらにしろ、const外しキャストが必要になり好ましくないね
私のない頭では「発見したオフセットを戻り値として、str + 戻り値を呼び出し元で作ってね」というCっぽくない(ポインタのない言語では普通の)方法しか思いつかない
castがお嫌いなら、Cには、unionってやつもあるけどねー。だいたいconst剥がしキャストがC99で未定義とか誤解じゃろ。n1124読んだけど、書いてないだけで、undefinedと書いてあるわけじゃないし。6.7.3.5には、const修飾されて定義されたobjectをnon-constなlvalue経由で書き換える行為はundefinedって書いてあるんだが。
書き込みをしなければどうということはない
本当だ、C言語ではconst外しキャストそれ自体が未定義動作なのか。じゃあ今回のLLVMの変更はまだ穏当な方だな
本当だ、C言語ではconst外しキャストそれ自体が未定義動作なのか。
https://kikakurui.com/x3/X3010-2003-01.html [kikakurui.com] に
const修飾型で定義されたオブジェクトを,非 const 修飾型の左辺値を使って変更しようとした場合,その動作は未定義とする。
とはあるけど「本当だ」って何が?
とりあえず、型変換の話なんだから型変換の節を読みなよ。型修飾子の節に型変換の話が載ってるわけないでしょ。
より多くのコメントがこの議論にあるかもしれませんが、JavaScriptが有効ではない環境を使用している場合、クラシックなコメントシステム(D1)に設定を変更する必要があります。
身近な人の偉大さは半減する -- あるアレゲ人
キャストでconstを外すのがバグではなく (スコア:1)
その結果定数メモリへの書き込みが発生するのがバグ
Re:キャストでconstを外すのがバグではなく (スコア:1)
組み込みやってるとconst領域はROMに確保されるのが当たり前だったのでconst付シンボルの中身を書き換えてるソース見て何だこりゃ?って思ったっけ。
(そのソースをそのまま組み込み機に移植したら動かなくなったのを思い出した)
#それを相性問題で片づけたのはうちの上司
#(Windowsプログラマ部隊より立場弱くて、更に「実績のあるソースだからそのまま使え」の通達付きだった)
Re: (スコア:0)
組み込みで使われがちなbusyboxもこのバグを踏んでいたというのがなんとも
Re: (スコア:0)
>const領域はROMに確保されるのが当たり前
それをリンカに指定するまでが組み込みプログラマの責任
セクションて知ってる?
(方言でセグメントと言うかもしれん)
それにしてもすごい会社だなそこ
Re: (スコア:0)
ところで、定数が定数であることはだれの責任なんでしょう?
当時とった解決策(既設ソースは変更不可のため)。
RAMが無駄に余裕があったので、全セクションをROMに配置したのち
起動時にROM領域を全部RAMにコピーしてジャンプする疑似ブートローダーのバイナリ作って
ビルド済みライブラリとしてROMイメージにくっつけた。
#要はPC(Windows)と同じくconstも初期値付き変数も、全部RAM上ならいいんでしょ。となった。
#後にGPIOの空き端子にジャンパピンが追加され、新旧2種類のROMイメージから起動できるようになった。
#当然最初の要求仕様にはない追加仕様で泣きつかれた結果である
Re: (スコア:0)
>PC(Windows)と同じく
MMUがREADONLYにしているんだよw
Re: (スコア:0)
>Nの社風なんだろうか?
これはぜってーH社じゃない、F社なんかあり得んだろと思って読んでたら
ほーらやっぱり
Re: (スコア:0)
ところで、定数が定数であることはだれの責任なんでしょう?
当時とった解決策(既設ソースは変更不可のため)。
RAMが無駄に余裕があったので、全セクションをROMに配置したのち
起動時にROM領域を全部RAMにコピーしてジャンプする疑似ブートローダーのバイナリ作って
ビルド済みライブラリとしてROMイメージにくっつけた。
それが、できるならまだ恵まれてる。大昔担当した官公庁向けシステムで同様のパターンの時はそれすらRAM不足で不可でした。(後述のT社とは別件)
結局、当該ソースにバグ回避用ラッパー(バグ条件に合致したら制御を乗っ取る)や、それでも回避できない部分は、(現場担当者に断って)闇パッチで対応したり。
#当該システムは設置された施設ごと
Re: (スコア:0)
その会社の調達のルートではNANDなROMが高いとか。
しまった、間違えた。
×NAND
○NOR
Re: (スコア:0)
ははは、俺が参加したNのプロジェクトもRAMが空いててROMの一部をRAMに移動してた。
Re: (スコア:0)
最近、破綻するプロジェクトのニュースをよく見るので、IT奴隷ばっかりが増えてプログラマーがいなくなったのかと嘆いていましたが、ここのコメントを見る限りプログラマーが健在だと安心しました。
というか、皆さん現役ですよね。2000年ごろの話してませんよね。
(X68000とかは明らかに90年代だけど)
Re: (スコア:0)
(X68000とかは明らかに90年代だけど)
80年代やぞ
Re: (スコア:0)
年取るとね、昔語りばかりするようになるんですよ。
あと10年程度ならつい最近とか思っちゃうの。
年取るってほんと怖いんだよ。
Re: (スコア:0)
自分の中じゃあんときのまんまだもんね
いまだにテイラー・スウィフトとか聞いて萌え萌えしてるかんなー
意図して September [youtube.com] とか避けてる
Re: (スコア:0)
自分が萌え萌えしたのは、読込みはROMから、そのアドレスに書込むとRAMに書き込むというコメントかな。
Z80のR/W端子を思い出して、ああ昔はいろいろできたなぁ。って懐かしくなった。
(今もできるだろうが、モジュール化・ワンチップ化されている今では、コストばかりかかって非現実)
Re: (スコア:0)
本当に組み込みの方?
今回の話は、コンパイラでどの変数をどのセクションに割り当てるかという段階の話でリンカ云々以前の段階です。
そして、固定データを格納するセクションに割り当てられていれば、多くの組み込みではROMに割り当てられるというだけです。
Re: (スコア:0)
>本当に組み込みの方?
おっおぅ、ExcelVBAにシリアルI/OやTCP/IP実装したりする変態的な組み込みの方だぞ。
(こうゆう変態的要求仕様を出して来るのはNだけだとは思いたい)
セクション切るのはリンカオプションだったが、この辺は開発環境によるのかな(当時使ってたHEWではリンカオプションだった)
const外すのも、#pragma section切るのもNに却下された。
今にして思えば、stdio.hあたりをプロジェクト内部にもって
そこでセクション切ってゴニョゴニョしたらブートローダーを2段に噛ますようなアクロバットはしなくて済んだかも。
Re: (スコア:0)
>それをリンカに指定するまでが組み込みプログラマの責任
あまり良くわかっていなくて申し訳ないのですが…。
以下のようなものかなと思うのですが、
const int *v = (void *) 0xFFFFE0000;
(int *)v = 1;
リンカがどう関係するのでしょうか?
Re: (スコア:0)
ポインタ経由すればconst付きで宣言した変数の書換だってできますからね。
まあROMに書き込見たいときとか値を固定したいときはdefine使えと。
Re: (スコア:0)
> ポインタ経由すればconst付きで宣言した変数の書換だってできますからね。
それ処理系依存
GCC とかだと最適化のオプション次第ですけど普通に使ってれば SegFault です。
Re: (スコア:0)
処理系依存ではない。書き換えは未定義動作。「any attempt to modify a const object during its lifetime (3.8) results in undefined behavior.」
Re: (スコア:0)
未定義動作は処理系がどのように実装しても構わないのだから、処理系依存で間違ってないと思うが。
Re: (スコア:0)
constからdefineに戻れと・・・。それは流石に方向性間違ってませんか・・・。
Re: (スコア:0)
define undef defineで値を変更できるので定数化にもなりませんし
Re: (スコア:0)
boot時は、読み出しはROMでも書き出しはRAMに書かれ,ROMをdisableするとその後はRAMから読み出すようになるっていうのはあったような。
まぁ、そういうエリアをconst修飾するってことは少ないでしょうけど、ROMのアクセスは遅かったのでROなセクションでもRAMに展開する意義はあった。
Re: (スコア:0)
X68000がそんな感じだった覚えがあります
速度というよりはベクターテーブルを書き換え可能にするためだったかな
※ベクターテーブルも含めた先頭から64kbの領域にIOCS(BIOS)をROMとしてマップしてた
Re: (スコア:0)
constはその領域が定数メモリ(ROM)である事を宣言するものではないので
キャストの結果書き込みが発生しても、それはプログラマが書いた通りの挙動。
例えばBIOS ROMがFlash Memoryだとして、普段は読み出し前提でconstを付けてるけど
BIOS更新用の関数内だけはあえて非constにして書き換えを出来るようにしたとして
それはバグでもなんでもないわけです。
# そんな書き方をしたソースじゃ後でメンテで死ぬ、という話は別問題
Re: (スコア:0)
未定義動作を踏んでるのでちょっと違う。その場合、コンパイラ・実行環境は、プログラマが書いた通りに実行する義務を負わない。
「そうは言っても実際問題ちゃんと動くことを確かめてから本番環境に突っ込んでるし、その後もちゃんと動いてるからええやろ」みたいな意見もよく見かけるけど、そのプログラムがちゃんと動く事を誰も公式には保証してくれてない状態なので、ある日突然コンパイラを作ってる側の人の気分で挙動が変わるかも知れない。まさにこういう問題が起こっても自業自得としか言えない。
Re: (スコア:0)
未定義動作である以上、起動後即時リターンコード0で終了するバイナリが生成されても文句は言えない。
参考:https://cpplover.blogspot.com/2014/06/old-new-thing.htm
鼻悪魔はジョークだけどタイムトラベルは比較的現実のリスクってーのがまたなんとも……
Re: (スコア:0)
Cで完全に合法的なstrchrってどう実装するんだろう?
Re: (スコア:0)
メモリーリークしまくりの毎回mallocしっぱなしか
関数内部にstatic領域を準備してそこにコピーして返すスレッドアンセーフですかね
たぶん作られた当時はスレッドセーフを考慮してなかったろうから後者かな
可変長にするなら内部の領域をchar配列ではなく0初期化済みのcharポインターにしてmalloc+reallocでサイズ更新
開放はプロセス終了時処理にまかせるとか
Re: (スコア:0)
規格に対してはそうかもしれないが、道具としてコンパイラを使う方からしてみたら
「未定義動作だよ」と警告を出すか、
すなおにsegmentation faultになってバグを顕在化できる
ほうが嬉しくないか?
期待以外の結果なのに一見動作しているように見えるというのは害悪だと思うが。
Re: (スコア:0)
現実には定数を書き換え不可能領域に配置するコンパイラ/リンカはありふれているわけで、仕様としてはどっちにするのか、それとも現状のまま「仕様としては定めない、実装依存」とするのかという話になりそう
「普段はconstだけど限られた特定の場合だけ書き換えたい」なら「書き換えが必要な処理だけ独立した別processとかにしろや」と思う
Re: (スコア:0)
C++のconstはオブジェクトの定数性を示すものであって、定数ではない(ことにできる)。
すくなくともクラスのインスタンスは。(ref. mutable)
たとえばキャッシュを内蔵したクラスで使ってるのを見たことがある。
Re: (スコア:0)
非修飾型へのポインタを修飾型へのポインタにキャストするのは許容されているが、逆は未定義動作だろ
Re:キャストでconstを外すのがバグではなく (スコア:1)
すくなくともC++では未定義ではないな。
それ経由で書き込むと未定義。読むのはOK。
Re:キャストでconstを外すのがバグではなく (スコア:1)
C++は知らんが、Cではポインタの型変換について修飾付ける方向のしか規格に記載されていないから、const外しキャストは未定義動作になる。
strchrとか標準関数ですらreturn値でconst外してくるあたり、規格自体が狂ってる感はあるけども。
Re: (スコア:0)
> strchrとか標準関数ですらreturn値でconst外してくるあたり、規格自体が狂ってる感はあるけども。
それはアタナの勘違い
const char * strchr ( const char * str, int character );
char * strchr ( char * str, int character );
プロトタイプ宣言が2つあります
Re: (スコア:0)
それはアタナの勘違い
const char * strchr ( const char * str, int character );
char * strchr ( char * str, int character );
プロトタイプ宣言が2つあります
Cでそんなことできたっけかな?
const char * strchr ( const char * str, int character );
char * strchr ( char * str, int character );
int main(void)
{
}
https://wandbox.org/permlink/k4ROmZcUnxTwh7Ab [wandbox.org]
prog.c:2:20: error: conflicting types for 'strchr'
2 | char * strchr ( char * str, int character );
|
Re: (スコア:0)
それはアタナの勘違い
const char * strchr ( const char * str, int character );
char * strchr ( char * str, int character );
プロトタイプ宣言が2つあります
X3010の草案(?) [kikakurui.com]だと
7.21.5.2 strchr関数
形式
#include
char *strchr(const char *s,
Re: (スコア:0)
それC++のstd::strchrだろ、Cには関係ない。
Re: (スコア:0)
最初に「C++は知らんが、Cでは」と書かれているのすら見えないバカがいるのか
Re: (スコア:0)
これはconstやキャストの問題ではなくstrchrの戻り値をconst char*にすべきだったという問題だと思いますね
Re:キャストでconstを外すのがバグではなく (スコア:1)
strchr自体は、strを書き換えないので、引数はconstでいい。
戻りは、呼び出し元が書き換えたいニーズもあるので、裸でいい。でないとキャストがいる。
書き換えないなら、const char*な変数にでもうければいい。こっちはキャストいらない。
Re: (スコア:0)
strchrの戻り値がchar *の場合、strchrの内部でconst外しキャストが必要
strchrの戻り値がconst char*の場合、呼び出し元で(書き換えたいときは)const外しキャストが必要
どちらにしろ、const外しキャストが必要になり好ましくないね
私のない頭では「発見したオフセットを戻り値として、str + 戻り値を呼び出し元で作ってね」という
Cっぽくない(ポインタのない言語では普通の)方法しか思いつかない
Re:キャストでconstを外すのがバグではなく (スコア:1)
castがお嫌いなら、Cには、unionってやつもあるけどねー。
だいたいconst剥がしキャストがC99で未定義とか誤解じゃろ。n1124読んだけど、書いてないだけで、undefinedと書いてあるわけじゃないし。
6.7.3.5には、const修飾されて定義されたobjectをnon-constなlvalue経由で書き換える行為はundefinedって書いてあるんだが。
Re: (スコア:0)
書き込みをしなければどうということはない
Re: (スコア:0)
本当だ、C言語ではconst外しキャストそれ自体が未定義動作なのか。じゃあ今回のLLVMの変更はまだ穏当な方だな
Re: (スコア:0)
本当だ、C言語ではconst外しキャストそれ自体が未定義動作なのか。
https://kikakurui.com/x3/X3010-2003-01.html [kikakurui.com] に
const修飾型で定義されたオブジェクトを,非 const 修飾型の左辺値を使って変更しようとした場合,その動作は未定義とする。
とはあるけど「本当だ」って何が?
Re: (スコア:0)
とりあえず、型変換の話なんだから型変換の節を読みなよ。
型修飾子の節に型変換の話が載ってるわけないでしょ。