2017年3月10日

[py2]16進数値と16進数文字列

何度やっても覚えられない、python2での16進数と文字列の変換。

 

16進数値を、16進数文字列に変換
http://hiro99ma.blogspot.com/2017/01/py216str.html

>>> x = 0x0123456789abcdef
>>> format(x, '016x')
'0123456789abcdef'

 

16進数文字列を、16進数値(というか、数字)に変換

>>> y = '0123456789abcdef'
>>> int(y, 16)
81985529216486895L
>>> format(int(y, 16), 'x')
'123456789abcdef'

 

これでしばらくは大丈夫なはずだ。。。

2017年3月9日

[js]nullは0じゃない

今日、ちょろっとJavaScriptを触っていた。
もちろん、詳しくない。
最近触っているというか、触らざるを得ないからやっているのだが、とてもつらい。。。

 

今日は、グローバル変数と呼んで良いのか? varを付けずにアクセスする変数を作りたいと思った。
とにかくカウントアップする変数を用意したかったのだ。

ただ、どこから呼ばれるかはっきりしないので、初期化するタイミングに悩んでいた。
そういえば、変数に代入されてないことの確認で、

if (!value) {
  ...
}

みたいに書けたと思うから、初期値は0ってことじゃなかろうか。

ということで、こう書いた。

count++;

 

はい、動きませんでした。。。
たぶん、例外が発行されたのだと思う。
meteorを使っていたから、meteorが例外を出していたのだけど、たぶんそうだろう。

デバッグ用だったから、onRendered(meteorのしくみね)で

count = 0;

とすると、動いた。

なるほど、0じゃなくて、nullなんだ。
そして、nullだからインクリメントなんてしたらいかんのだな。

 

普通のJavaScriptだったら静的解析ツールなんかに掛けることもできそうだけど、meteorだと文法がちょっと違うためか、うまくいかなかった。
C/C++を主に使っているので、コンパイルエラーが出なければそこそこ動くだろう、と思ってしまうのだが、そうじゃない世界に放り込まれると、けっこうつらいですわ。

[c/c++]先頭にアンダーラインを付けようとしたが、やめた

前回の続きだ。

static library、まあ「*.a」のファイルと思ってもらえば良いか。
そのタイプだと、単にオブジェクトをまとめただけなので、オブジェクト間で共有したい関数をstaticにすることができない。
だから、リンクする人には見えてしまう。

 

今まで、それが嫌な場合は、#includeでソースファイルをインクルードさせることで、ファイルだけ分割させることがあった。
目的は果たせるのだけど、すっきりしないので、コンパイラ依存でも良いから方法があるなら何でもよかったのだ。
しかし、方法がまだ見つかっていない。。。

 

そこでふっと思い出したのが、アンダーライン「_」だ。
システムなどが使うから、先頭にアンダーラインを付けた名前はいかんよ、というルールだったと思う。
今こそ、そのアンダーラインを使うときでは無かろうか?

・・・アンダーラインを付けないようにしたルールって、なんだっけ?


今回は、オライリー『Cクイックリファレンス』で調べる。
どの章になるのか分からなかったが、「16章 標準ヘッダ」の、"16.1.3 予約識別子"がよかろう。

思ったより、幅広いルールだった。

  • 2つの下線または下線の後に英大文字から始まる識別子は予約済み
  • 下線から始まる他のすべての識別子はファイルスコープで識別子として予約済み

えーっと、まず、下線2つはダメ。
下線1つと大文字も、ダメ。

ファイルの中で閉じているなら、下線1つと小文字ならOK。
staticな関数や変数、引数やマクロ名なんかには使えるけど、公開する関数名には使えない。

ほぼ全部やん!
残ってないやん!!
この項目の前に「標準ライブラリで」と書かれているので、何とか逃げようと思ったが、そんな無理はやめた方がよいだろう。

 

識別子の先頭として使える文字で"_"でないものを考えていたが、よいものがない。
VC++などであれば日本語のようなものも使えそうだが、どのコンパイラでもというのは難しいだろう。

うーん、アンダーラインのルールはもう少し緩くしてほしかったところだ。
2つはダメだけど、3つは使ってよい、とか。

実際のところ、アンダーラインで始まった名前を使ったとしても、コンパイルエラーになることはないだろう。
もしなったら、別の名前にすれば良いだけのことだ。
ただそれは、「車が通っていないから赤信号だけど渡ってしまおう」というのと同じで、問題はないけど割り切れない感じが残ってしまう。

 

私の模索は続く。。。

2017年3月7日

[c/c++]static libraryで非static関数を隠すのは無理そうだ

2017/03/11 続編
[c/c++]static libraryでAPIを隠すのにもvisibility("hidden")が使えそう

ソースファイルが長くなってきたので、ファイル分割した。
長いと、スクロールするのが面倒なのでね。

そこまではよかったのだが、ファイル間で使いたい関数があった。
その関数は後悔するようなものではないのだが、ファイル間なので公開しないと使えない。
名前ルールで、いかにも公開してなさそうな名前にしても良いが、今後も出てくると思うので、コンパイラ依存で良いから解決できるのならやっておきたい。

 

こういうときは、オライリーのBinary Hacksだろうと眺めると、#29に載っていた。
載っていたのだが・・・これはshared libraryでのやり方だ。
__attribute__((visibility("hidden")))というやり方も書いてあったのだが、arでオブジェクトをまとめるだけではさすがに使えない。

まあねぇ。。。
リンクしないと、"hidden"といわれても、やってよいかどうかわからないだろう。

 

こちらに、詳しく説明があった。

http://stackoverflow.com/questions/22244428/hiding-symbol-names-in-library

うん、ダメなものはダメ、ということだ。

2017年3月6日

[c/c++]最近gotoが多い

個人的な傾向なのだが、最近エラー処理でgotoを使うことが多くなってきた。

   ret = xxx_func();
   if (!ret) {
     goto FIN;
   }
   ...

FIN:
  return -1;
}

 

goto禁止というところも多いのだが、今は自分のルールでソースを書けるため、単に個人的な傾向なのだ。
私としては「gotoの乱用はよろしくないが、局所的ならいいんじゃないの」というスタンスでいる。
C++だとtry-catchという手段もあろうが、Cだとそういうものがないので、gotoで飛ばしているのだ。

 

しばらく前は、こういう書き方をしていた。
あ、retはboolと思っておくれ。

  ret = xxx_func();
  if (ret) {
     ret = yyy_func();
  }
  if (ret) {
    ret = zzz_func();
  }
  ...

こういう書き方をしたこともあった。
本か何かで見かけたのだと思う。

do {
  ret = xxx_func();
  if (!ret) {
    break;
  }
  ret = yyy_func();
  if (!ret) {
    break;
  }
  ...
} while (0);

 

まあ、どう書くにしても、

  • 戻り値を取得
  • 戻り値をif文でチェック
  • エラーだったら何かする

という処理を書くという点は同じだ。
その見せ方や流れが違うだけだろう。

 

do-while(0)はいいかな、と思っていたのだけど、トリッキーとまでは行かないが、ちょっと変則的な気もする。
だから、ifを連続して書くパターンを使うことが多かった。
最初のチェックでNGだったら、以降もずっとNGなのに、if文のチェックを全部やらないと処理を抜けられないので、なんだかなぁ、という気持ちはあったけど、まあ複雑になるわけでもないからよいか、と思っていた。

けれど、多重ループから抜けて終わらせたい、というパターンが出てきた。
内側のループと外側のループを抜けるためにどうするか?ということを考えているうちに、だんだん面倒になってきて、もうgotoで抜ければいいやん、になったのだろう。
そして、1箇所gotoで抜けたら、他もそのルールに合わせた方が自然な流れになるか、ということで、gotoを使うことが多くなったのだと思う。

 

最近使っているmbedTLSだと、その辺をマクロで隠蔽している。
MPI_CHK()みたいなマクロがあって、戻り値をretに代入し、0以外だったらgotoでcleanupラベルに飛ばしている。
だから呼び元では、

  • ret変数の宣言
  • cleanupラベルと、その後に後始末を書く

だけやっておけば、勝手にやってくれる(ように見える)。
他のOSでは、TRY-CATCHみたいなマクロを作っていて、それはlongjump()などを隠蔽していた記憶がある。

そういうマクロがあると、ソースはさっぱりして見えて良いのだけど、何をしているか知らずに使っていると思わぬ失敗をしてしまうこともあるので、気をつけたいところだ。

かといって、マクロを用意していなかったら、各人が好き勝手にエラー処理を書いて、それはそれで読みづらくなったり、エラー処理が漏れていたりすることもあるので、リズム良く書けるのであれば良いな、と思う。

2017年3月4日

Makefileの:=

前回、Go言語の「:=」がshort variable declarationで、ブロック内なら型を書かずに使えるということがわかった。

 

そういえば、Makefileも「=」と「:=」の違いがあったが、なんだっただろうか?
Makefile における := と = の違い - Qiita
なるほど、中身を評価するタイミングが、「=」だと使うタイミングで、「:=」だと代入するタイミングということか。
「=」だと、結果じゃなくて式自体を保持しておかないといかんから、コストが高いのかな。

 

そういえば、JavaScriptで、タイミングの違いに注意という記事を見た記憶がある。
[Javascript] 関数宣言の落とし穴 function foo ( ){..} と var foo = function ( ) {..} は動作が違うので要注意! · DQNEO起業日記
すまぬ、わからんかった。。。

JavaScriptって、言語として難しく感じてしまう。
Pythonでスクリプト言語に多少慣れたから、そろそろいけるんじゃないかと思ったけど、ダメだった。
数年で1回くらいのペースでしか使わないのだけど、今月がそれなのよねぇ。。。

[golang][雰囲気]varがない変数らしきもの (2)

前回の続き。
変数っぽいけど、varしているところがファイル内にないが、なんなんだ?という疑問を持っていたのだが、これのようだ。

https://golang.org/ref/spec#Short_variable_declarations

「:=」を使うと、型宣言をせずに使えるらしい。
そうか、あのコロンにはそういう意味があったのか。。。
たまたま気がついた変数がそうだっただけで、他にも使われているわ。

同じブロック内か、パラメータリスト(引数のこと?)という制限はあるようだ。
「at least one of non-blank variables is new」とあるけど、これは何だろう。
nilがダメなのかと思ったが、untyped nilと怒られるので、それとは意味が違うのかもしれん。
(nilは検索するといろいろ出てきたので、今回は触れずにおこう。。。)

2017年3月3日

[golang][雰囲気]varがない変数らしきもの (1)

なんとなくの知識で、Go言語で書かれたソースファイルを読んでいる。

 

読んでいるソースファイルで、

  • varが付いていないのに代入している
  • そのファイル内で何箇所も出てくる
  • ファイル内では、varが付いていない。

となっていたので、これはグローバル変数だろう、と当たりを付けた。
が、他のファイルを検索してもvarしている箇所がない。。。
MeteorでJavaScriptを書いていて、varを付けたり付け忘れたりで苦労しているのだが、Goもそういう言語なのだろうか?


宣言とスコープ
Declarations and scope

スコープ制御は、ブロックを使うとのこと。
ブロックは、{...}の中のことで、ここはCなどと同じようだ。
そして変数の宣言は、varが付く、となっている。
では、今回見つけたやつは、グローバル変数ではないし、そもそも変数ではないということか。

 

じゃあ、なんなのだ?
代入されて、メンバ関数を呼び出しているようなので、単なるエイリアスのような感じもする。
でも、Go言語のaliasは「alias type」みたいなので、typedef相当なのかも。

デバッグすれば分かると思うのだが、ソースだけで何とかしたいのだ。。。
時間がないので、次回に続きます。

[golang][雰囲気]スライス (2)

前回は、Go言語のスライス型だけ読んだ。
今回はスライスを読んで、終わりにしよう。

 

・・・あっさりした説明だった。


まずは、書いてあるとおりに実装してみよう。

01: package main
02: 
03: import "fmt"
04: 
05: func main() {
06:     a := [5]int{1, 2, 3, 4, 5}
07:     s := a[1:4]
08:     fmt.Printf("a=%s\n", a)
09:     fmt.Printf("s=%s\n", s)
10: }

結果

a=[%!s(int=1) %!s(int=2) %!s(int=3) %!s(int=4) %!s(int=5)]
s=[%!s(int=2) %!s(int=3) %!s(int=4)]

 

%sは「文字列またはスライスそのまま」らしい。
じゃあ、配列を%sで出力できると言うことは、配列もまたスライスに属するということだろうか。

いや、そもそも%sで文字列もスライスも配列も出力できるということは、%sは連続したメモリ領域を要素型に向けた出力形式で掃き出す、という意味を持つということか。
Cだと配列の要素数はsizeofでしかわからないし、文字列は\0で終わるというルールなので、こういうことはできなかったのだよな。

あ・・・・出力に「!」が入っているのは、エラーなのか。
つまり、エラーだけど出力してやったよ、ということなのか?
検索すると、%vというものがあるらしいので、変更して動かした。

a=[1 2 3 4 5]
s=[2 3 4]

うん、こっちの方が素直な出力だ。
ちなみに、%#vにするとこうなった。

a=[5]int{1, 2, 3, 4, 5}
s=[]int{2, 3, 4}

 

では、%sでスライスを出力できるというのは、なんなのだ?
英語版を見たけど、「the uninterpreted bytes of the string or slice」となっているので、

(the uninterpreted bytes of the string) || (slice)

だと読み取っているのだけど、もしかしたら、

the uninterpreted bytes of (the string || slice)

なのだろうか?

Google翻訳:「文字列またはスライスの解釈されていないバイト」
excite翻訳:「ストリングまたはスライスの解釈されていないバイト」
weblio英語翻訳:「ひもまたはスライスの解釈されてないバイト」
golang.jp:「文字列またはスライスそのまま」

うーん、こうやって並べると、or条件は「文字列かスライス」で、それにuninterpreted bytesがかかるというのが有力なのか。

では、私が最初に思ったように、orがスライスだけになるような文章はどういう書き方なのだろうか。

Google翻訳:「文字列の解釈されていないバイトまたはスライス」→uninterpreted byte or slice of string

えー、なんか違う気がする。。。
念のため、スライスをご飯にしてみよう。

Google翻訳:「文字列の解釈されていないバイトかライス」→uninterpreted byte or rice of string
Google翻訳:「文字列の解釈されていないバイトかご飯」→byte or rice not interpreted as a string

だんだん、何をしたかったのか分からなくなってきた。。

英語は、対象物を一番最後に置くような言語だったと思う。
SVCなり、SVOCなり。
だから、修飾する言葉が前にあって、その後ろにorで並んでいたら、その修飾はorしている両方にかかるということか。
もし、私が思ったように一部だけかかるようにしたいなら、orがまだ前に来るように並べるか、コンマで区切るとか、そういう対策をするんじゃなかろうか。

 

では、最初の疑問に戻って、%sだ。
Printf()で!が出力されるのはエラーということだが、%sでスライスを与えてもエラーになった。
では、%sで出力される文字列ではないスライスというのは、どういうものなのだろうか?

英語版の方では、%vを使った場合に、要素型に対応するフォーマットが書かれている。
%vでint型を表示しようとしたら、それは%dになりますよ、というような対応だ。
そこにはsliceが書かれていない。
もしかしたら、%sのsliceは、文字列のslice、つまり部分文字列を指しているだけなのだろうか?

 

また何か分かるのかもしれんが、集中してsliceのことを調べるのはここまでにしよう。

2017年3月2日

[golang][雰囲気]スライス (1)

お仕事で、Go言語のソースを読もうとしている。
書こうとしている、ではない。
読むだけだ。

もちろん、読み書きできるのが一番良いし、望ましいのだが、いかんせん時間が無い。
あちこち目をつぶって、雰囲気だけつかむことを目指す。


その第1弾が、スライスだ。

 

スライス型
http://golang.jp/go_spec#Slice_types

スライス
http://golang.jp/go_spec#Slices

スライスは「ある配列内の連続した領域への参照」と書いてある。
そしてスライス型は「その要素型と同じ要素型を持つ配列のすべてのスライスの集合」らしい。

なぜ配列とは別になっているのだろうか?
配列内で、連続した領域を参照しているなら、それはそれで配列なんじゃなかろうか。。。

いま思っているのは、太枠が配列だとしたら、赤い部分がその一部を参照しているうスライスだ。
スライスは要素が0から始まると書いてあるので、こうなるはず。

image

 

 

スライス型の1項目前が「配列型」だった。
http://golang.jp/go_spec#Array_types
配列も型なんだ・・・。
説明だけ読むと、配列型は要素型の要素を複数持っていて、インデックスで連番アクセスできて、長さも持っている、というだけのようだ。
他の言語と同じように見える。
まあ、C/C++の配列は要素数を持たないけどね。

 

スライスは、キャパシティ、という概念があるようだ。
ちょっと違うが、STLのsize()とcapacity()みたいな雰囲気がある。
上の図だと、capacityは5になるはず。

 

make()で新しいスライスを作ることができるらしい。
・・・ん?
makeの引数に、要素型と長さの指定、capacityまで指定はできるけど、そもそも参照型だから「誰のどこから」という情報がいるんじゃなかろうか。
「隠された配列を新たに割り当て」など、参照するという言葉の意味が分からなくなってくる。。。
新しい領域を割り当てるんだったら、それはもう配列でよいんじゃないのか??

 

まだスライス型のところを読んだだけなので、次の「スライス」を読むと謎が解決するのかもしれない。
ともかく、今回はここまで。