2016/09/08

[c/c++]私のC言語 (14) - const volatileなんてものがあるのか

だんだん「私の」が何を意味しているのかわからなくなりつつあるが、深くは考えまい。
コーディング作法ガイドをまだ読んでいるが、いろいろ知らないことが出てくる。

 

今回は、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 件のコメント:

コメントを投稿

コメントありがとうございます。
スパムかもしれない、と私が思ったら、
申し訳ないですが勝手に削除することもあります。