2018年7月29日日曜日

C言語ポインタ完全制覇

「C言語ポインタ完全制覇」の第二版が発売されています。古い表紙版は既に持っているのですが、内容も更新されているので、嬉しくて買ってしまいました。

学校に置いて行ったり、友人に渡したり、買いまくってましたw

この本がなかったらC言語を扱うことを諦めていたような気がします。

「OS自作入門」や「CPUの創り方」の影響ももちろん大きかったと思うのですが、この本を読んでいなければC言語をそれなりに扱えるようにはなれなかったと思います。

C言語疑問とメモ:構造体の宣言と定義

以下の内容は個人的メモであり、誤りが含まれている可能性があります。ご注意ください。
CについてはN1570を、C++についてはN3337を参照しています。

構造体の宣言と定義

struct Tag {
    char member1;
    int member2;
};

これは何を意味するか考える。

構造体・共有体指定子中の{...}部分(の存在)は、その翻訳単位内で新しい型の宣言をする。(6.7.2.1p8)

{...}を含む構造体、共有体、列挙型の型指定子は、それぞれの型を宣言する。
{...}の部分は、それらのコンテンツを定義する。
型指定子に識別子が提供された場合、その型指定子はその型のタグとなる識別子も宣言する。(6.7.2.3p6)

(6.7.2.3 Tagsの制約として)ある型は、最大一回だけ定義されたコンテンツ(内容)を持たなければならない(持てる?)(shall have)(6.7.2.3p1)

コンテンツとは、(6.7.2.3p6)から、構造体の持つ要素であると言える。

同じタグを持ち、同じスコープを持つ構造体型、共有体型、列挙型の宣言は、同じ型を宣言する。(6.7.2.3p4)
ある翻訳単位に、ある型のタグや他の宣言があるかどうかにかかわらず、コンテンツの定義のとじカッコ(})が現れるまでは不完全型であり、その直後に完全型となる。(6.7.2.3p4)

識別子は、オブジェクト、関数、構造体や共有体や列挙のメンバ名かタグ、typedef名、ラベル名、マクロ名、マクロ仮引数を、一つ示す(意味する、表す)ことができる。(6.2.1p1)
宣言は識別子の解釈と属性を明示する。(6.7p5)
オブジェクトのストレージの割当を引き起こす、オブジェクトの識別子の宣言は定義である。(6.7p5)
関数の本体を含む識別子の宣言は定義である。(6.7p5)

なお、無名の構造体(タグも識別子も持たない、構造体のコンテンツの定義のみを行う)は文法上構造体などの内部でしかできないと思う(ちゃんと確認はしていない)(6.7.2.1p1)

以上のことから、最初のコード片は、
「新しい構造体型の宣言と、構造体を示す識別子(=タグ)の宣言であり、さらにその識別子が示す構造体型のコンテンツを定義している」
と考える。

C++では少なくとも、宣言のうち定義でないものが明確であり(3.1p2)、一般的な意味での「クラスの定義」とは何であるかはわかりやすい。(9p2)
C++の方が、部分的にはわかりやすい気がします。

2018年7月28日土曜日

C言語疑問とメモ:多次元配列は何故メモリ上で並んでいると言えるか

以下の内容は個人的メモであり、誤りが含まれている可能性があります。ご注意ください。
CについてはN1570を、C++についてはN3337を参照しています。

多次元配列は何故メモリ上で並んでいると言えるか(int[3][5])(ここでは可変長は考えない)
基本的には「多次元配列の宣言は宣言構文上、配列の配列(Array of array)の宣言である」からだと思う。
(6.5.2.1)に値を参照する場合の説明がある。

その他の前提となりそうな知識
配列とはオブジェクトの連続した(=隙間ない?)並びである。(6.2.5p20)
さらに、(6.2.6.1)より、オブジェクトはバイトの連続した並びである。
E1[E2] は (*((E1)+(E2))) と等しい。(6.5.2.1p2)

先頭要素へのポインタに+1すれば次の要素になることはどこで保証されている?
(6.5.6p8)で保証されると思う。

負の要素がないことはどこで保証する?
配列の要素数は1以上(6.7.6.2p1)と(6.5.6p8)の順序付けによって保証できそう。

配列のサイズ=要素数で良いのか?
(6.7.6.2p1)によれば、配列の宣言で指定しているのは配列のサイズである。
規格書が完璧に書かれていると考えれば、
* sizeofはオペランドのサイズを(バイト単位で)返す。サイズはオペランドの型で決まる(6.5.3.4p2)
* sizeofを配列型を持つオペランドに適用した場合、配列内の総バイト数を返す。(6.5.3.4p4)
であるので、「サイズ!=要素数」と考えたくなる。
そして、配列がオブジェクトの隙間ない並びであると考えれば、要素数はサイズによって決定できると言えそう。
ただ、「要素数を決めることはサイズを決めることである」というのは自明なことであって、わざわざそこまで厳密に書いていないのかもしれない。

規格書を引く場所を間違っているのだろうか?
この点については、C++はしっかり書いてくれている。(8.3.4p1)
ただ、C++では「boundを指定する」、という表現であるので、Cで「サイズを指定する」、というのは正しい表現なのかもしれない。

その他
無理にC言語を使わずに、C的な書き方をする場合でもC++を使ったほうが楽かもしれない。 C++の(3.9p4)のようなわかりやすい表現がCにもあればよいのに。

2017年9月16日土曜日

Raspberry PiのGUIが使いやすいかも

久しぶりにRaspberry PiのGUIを使ってみて、その使いやすさに驚きました。


必要な機能は揃っているし、軽快だし、シンプルだし…

あれ、Unityよりも使いやすいんじゃ…?

Ubuntuユーザーは、デスクトップ環境に関しては、旧GNOMEからUnityへの移行、そしてGNOMEへの回帰と若干翻弄され気味な感じがありますけど、あらためて軽量GUIを使ってみるといろいろ考えてしまいます。

もちろん、Linuxユーザーには選択の自由があるので、気に入ったGUIを使えばよいのだとは思います。

LXQtがうまく行ってくれると、Qtユーザーとしては嬉しいなぁ

2016年11月1日火曜日

Raspberry Pi2強制空冷

Raspberry Pi2にそれなりに重い処理をさせると熱が気になりますが、Webカメラサーバーと無線LANくらいであればヒートシンクをつけてケースに閉じ込めていても大丈夫なようです。

九州でも夏の間一度も停止することなく過ごすことが出来ました。RaspberryPiは意外と熱に強いようです。

ただ、やはりセンサー値で60℃を超えることもあるので、強制空冷を試してみました。

強制空冷と言っても、こんな感じでケースの上に8cmファンを直付しただけです。
ケースも下部に穴が開いているだけのものなので、ケースに直接風を当てることになります。

こんな雑な空冷意味がないだろうと思っていましたが、下のグラフのように10℃近く温度を下げることが出来ました。 空冷恐るべし。

この実験は秋に行ったものなので、夏場では外気温も上がり、もう少し効率は落ちるかもしれません。

ケースを殆ど密閉状態にしていても空冷できることがわかったので、基板がホコリまみれになる心配がなく、 長期的に安定稼働させられそうです。

さすがに常時回転させると気になるくらいの音が出るので、RaspberryPiからCPU温度によって回転数を制御してあげると良さそうです。

2016年7月23日土曜日

Inkscapeでグループ化した図形を変形するとtransform属性が付く

Inkscapeで作業している時に、水平半径と垂直半径を同じにしても矩形の角の丸みが同じにならない問題に悩まされました。

最初はバグかな、とも思ったのですが、XMLを見てみるとtransformという属性がグループに付いていることがわかりました。

グループ化されたオブジェクトを変形すると、transform属性がつくようです。 グループ化していることを忘れて単独の矩形を編集していたのが原因でした。

言われてみると当たり前なのですが、だいぶ悩まされてしまいました。

2016年6月28日火曜日

gitはC風に理解したらいいのかな?

gitをしばらく使ってみても、いまいちよくわからないままでした。 なんとなくスッキリしない感じでした。

でも、ふと「ポインタ」という用語を見て 「C言語風に理解できるんじゃないか?」 と考えてみると、少しだけ理解できたような気分になりました。

gitでのC言語で言うところの
tree,commit,blob,tag等のオブジェクト構造体の実体
ハッシュ構造体へのポインタ値
パス("refs/heads/master"など)構造体へのポインタへのポインタ値
ブランチ、軽量タグ構造体へのポインタ(型変数)
HEAD構造体へのポインタへのポインタ(型変数)
gitによる木、バージョン管理構造体のリンクリスト

という感じではないでしょうか? なんだか回りくどいような気もしますが…

追記1 : detached HEADの場合は直接コミットを指すようなので、HEADはvoid *型変数と言えるかもしれません。