アカウント名:
パスワード:
その結果定数メモリへの書き込みが発生するのがバグ
非修飾型へのポインタを修飾型へのポインタにキャストするのは許容されているが、逆は未定義動作だろ
すくなくとも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っぽくない(ポインタのない言語では普通の)方法しか思いつかない
const版と非const版用意するか、インデックスを返すか、プログラマの責任でconst付き変数で受ければいいだけ。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 修飾型の左辺値を使って変更しようとした場合,その動作は未定義とする。
とはあるけど「本当だ」って何が?
とりあえず、型変換の話なんだから型変換の節を読みなよ。型修飾子の節に型変換の話が載ってるわけないでしょ。
横レスだけど特に言及されてないよね。アクセス時に本体がconstだった場合だとか、暗黙で変換できるできないみたいな話はあるけど。指摘する側に提示を行ってほしいところ。
指摘する側ってどっちのことかわからないけど「規格が何の要求も課していないもの」が未定義動作なんだからconst外しキャストは未定義動作ではないって人たちに規格の課している要求を示してほしいな。修飾を付与した場合はキャスト前後で同値になると書いてあるけど、外した場合も同値になるとか書いてあるのだろうか。
#3692905 だけでは「constオブジェクトの変更について記載があるんだから、キャストで外せるはずだ!」っていう妄想でしかない。
「規格が何の要求も課していないもの」が未定義動作なんだから
「未定義の動作」も「未規定の動作」も「規格が何の要求も課していないもの」だけども、const外しキャストが前者であるという根拠は何?
妄想の類?
未規定の定義も知らんのか。「この規格が,二つ以上の可能性を提供し,個々の場合にどの可能性を選択するかに関して何ら要求を課さない動作。」「規格の提供した可能性から何を選択するか要求を課さない」のが未規定であって、何の可能性も示さないものは未規定ではない。
暗黙の型変換はそうだろうけど、普遍的に自由なキャストが未定義動作だったらvoid*とかどうなってんの?
https://twitter.com/shyouhei/status/1177407768430444545 [twitter.com]こちらの議論によると、"may be converted to a pointer to a different object type"の"different object type"にはconst修飾が異なる型も含まれるのでconst外しは可能、const付ける方だけわざわざ分けて書かれているのは歴史的経緯によるものらしい。
より多くのコメントがこの議論にあるかもしれませんが、JavaScriptが有効ではない環境を使用している場合、クラシックなコメントシステム(D1)に設定を変更する必要があります。
身近な人の偉大さは半減する -- あるアレゲ人
キャストでconstを外すのがバグではなく (スコア:1)
その結果定数メモリへの書き込みが発生するのがバグ
Re: (スコア:0)
非修飾型へのポインタを修飾型へのポインタにキャストするのは許容されているが、逆は未定義動作だろ
Re: (スコア: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: (スコア:0)
const版と非const版用意するか、インデックスを返すか、
プログラマの責任でconst付き変数で受ければいいだけ。
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)
とりあえず、型変換の話なんだから型変換の節を読みなよ。
型修飾子の節に型変換の話が載ってるわけないでしょ。
Re: (スコア:0)
横レスだけど特に言及されてないよね。
アクセス時に本体がconstだった場合だとか、
暗黙で変換できるできないみたいな話はあるけど。
指摘する側に提示を行ってほしいところ。
Re: (スコア:0)
指摘する側ってどっちのことかわからないけど「規格が何の要求も課していないもの」が未定義動作なんだから
const外しキャストは未定義動作ではないって人たちに規格の課している要求を示してほしいな。
修飾を付与した場合はキャスト前後で同値になると書いてあるけど、外した場合も同値になるとか書いてあるのだろうか。
#3692905 だけでは「constオブジェクトの変更について記載があるんだから、キャストで外せるはずだ!」っていう妄想でしかない。
Re: (スコア:0)
「規格が何の要求も課していないもの」が未定義動作なんだから
「未定義の動作」も「未規定の動作」も「規格が何の要求も課していないもの」だけども、const外しキャストが前者であるという根拠は何?
妄想の類?
Re: (スコア:0)
未規定の定義も知らんのか。
「この規格が,二つ以上の可能性を提供し,個々の場合にどの可能性を選択するかに関して何ら要求を課さない動作。」
「規格の提供した可能性から何を選択するか要求を課さない」のが未規定であって、何の可能性も示さないものは未規定ではない。
Re: (スコア:0)
暗黙の型変換はそうだろうけど、普遍的に自由なキャストが未定義動作だったらvoid*とかどうなってんの?
Re: (スコア:0)
https://twitter.com/shyouhei/status/1177407768430444545 [twitter.com]
こちらの議論によると、"may be converted to a pointer to a different object type"の"different object type"にはconst修飾が異なる型も含まれるのでconst外しは可能、const付ける方だけわざわざ分けて書かれているのは歴史的経緯によるものらしい。