だんだん「私の」が何を意味しているのかわからなくなりつつあるが、深くは考えまい。
コーディング作法ガイドをまだ読んでいるが、いろいろ知らないことが出てくる。
今回は、p.86に出ていた「const volatile」。
プログラムからは参照しかせず、別の実行単位から変更されるメモリのときに使うとよい、と書かれている。
別の実行単位というのは、スレッドとかタスクとかだろうか。
その場合、別の実行単位と同じメモリを参照しているはずだから、片方はexternになるんじゃなかろうか?
本体はconst無しで、externにconst有り、というのは警告されないんだろうか。
スレッドなどを作るのが面倒なので、ソースファイルを2つに分割して試したが、警告は出なかった。
もちろん、ちゃんと動く。
const有りの方で代入すると、ちゃんとコンパイルエラーになる。
ふーん。
さすがに逆はダメよね?
本体がconst有りで、externがconst無し、というパターンだ。
・・・警告が出ないし、ちゃんと動く。
ふーん。
片方にvolatile有り、もう片方にvolatile無しは?
いいんだ。。。
constもvolatileも型修飾子だから、飾り以上の意味を持たないと言うことか。
では、volatileは抜きにして、本体をconstを付けたint変数を、片方にextern intで、externした方で書き換えた。
いける。
ではでは、const intなのは同じとして、初期値を付けたらどうなる?
あ、警告などは出ずにビルドできるのだが、Segmentation Faultが起きた。。。
初期値があるとデータをROM側に持つけど、初期値がない場合は違うんだ。
cygwinのGCCだから、他のコンパイラだと違うかもしれんが、微妙なことはしたらいかんということだ。
リンクではじくしかないけど、Cだと名前だけじゃわからないからリンクしてしまうのか。
C++だと、そもそもconstのくせに初期値無しにするんじゃねえ(-fpermissive)と言われてコンパイルエラーになるし、初期値を入れてもリンクでちゃんと失敗してくれるな。
ちなみにconst定数は、CとC++で扱いが違うので注意がいるかも。
C++だとリンクが内部リンケージになるので、ヘッダファイルに置いても多重定義にならなくなるのだ(externしなければ)。
だから、C++ではマクロじゃなくてconst定数で書いてヘッダに置くこともできそうだけど、紛らわしいからやらない方がよいかもね。
やるなら、各ソースでstaticにするか、C++ならclassの中でstatic const intなどにするかな。
「プログラミング言語C++ 第3版」 p.246を読み返したが、constとtypedefがそうらしい。
前のプロジェクトで、ヘッダにconst変数を書いていて、それをstaticにしてるファイルがあったのを思い出した。
管轄外のソースだったので放置したけど、書いた人も放置した人も、お互い罪深いよねぇ。。。
0 件のコメント:
コメントを投稿
コメントありがとうございます。
スパムかもしれない、と私が思ったら、
申し訳ないですが勝手に削除することもあります。
注: コメントを投稿できるのは、このブログのメンバーだけです。