アカウント名:
パスワード:
その結果定数メモリへの書き込みが発生するのがバグ
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でサイズ更新開放はプロセス終了時処理にまかせるとか
strtokかなんかと勘違いしてないかな……?スレッドはCの側にそもそも入ってないので、スレッドセーフ化はスレッド導入した実装側の責任。まぁ、スレッドIDでスレッドローカルストレージ作れば済む話だよ。プロセス終了まで待たずともスレッド終了時にスレッド分の領域開放で済む。
strchrはconst char*を受け取ってその一部を指すchar*を返しちゃうので、const外しのキャストと同等の動作をするって事を言いたいんだと思う。テンプレートとかないからconst char*とchar*の両方で使える関数にする為こうなったんだろうな。const→非constのキャストをユーザがしなくて良いってだけの話に過ぎない。これに関してはconstを非constにキャストしてもそこに書き込みアクセスしなきゃ未定義動作にはならないし、ユーザ側が自分で戻り値をconst char*で受けさえすれば普通に合法なはず。
> スレッドはCの側にそもそも入ってないので、
C11にスレッドはありまぁす
それ以前のスレッドが一般化した時点での話な。まぁスレッドごとにTLS分のデータ持つロスはあれど、サードパーティも問題なく実装出来てたから企画が追従するのに問題はなかったわけだが。
# libc周りと協調しないAPIでスレッド作るとリークすっけど
より多くのコメントがこの議論にあるかもしれませんが、JavaScriptが有効ではない環境を使用している場合、クラシックなコメントシステム(D1)に設定を変更する必要があります。
あと、僕は馬鹿なことをするのは嫌いですよ (わざとやるとき以外は)。-- Larry Wall
キャストでconstを外すのがバグではなく (スコア:1)
その結果定数メモリへの書き込みが発生するのがバグ
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)
strtokかなんかと勘違いしてないかな……?
スレッドはCの側にそもそも入ってないので、
スレッドセーフ化はスレッド導入した実装側の責任。
まぁ、スレッドIDでスレッドローカルストレージ作れば済む話だよ。
プロセス終了まで待たずともスレッド終了時にスレッド分の領域開放で済む。
strchrはconst char*を受け取ってその一部を指すchar*を返しちゃうので、
const外しのキャストと同等の動作をするって事を言いたいんだと思う。
テンプレートとかないからconst char*とchar*の両方で使える関数にする為こうなったんだろうな。
const→非constのキャストをユーザがしなくて良いってだけの話に過ぎない。
これに関してはconstを非constにキャストしても
そこに書き込みアクセスしなきゃ未定義動作にはならないし、
ユーザ側が自分で戻り値をconst char*で受けさえすれば普通に合法なはず。
Re: (スコア:0)
> スレッドはCの側にそもそも入ってないので、
C11にスレッドはありまぁす
Re:キャストでconstを外すのがバグではなく (スコア:0)
それ以前のスレッドが一般化した時点での話な。
まぁスレッドごとにTLS分のデータ持つロスはあれど、
サードパーティも問題なく実装出来てたから企画が追従するのに問題はなかったわけだが。
# libc周りと協調しないAPIでスレッド作るとリークすっけど