C++のdecay

C++のテンプレート関係は難しくて、もともとのC++との整合性もあって複雑になっている。std::decayは配列とポインタの関係を扱ってテンプレートをより汎用的にするためのもの。

前提知識、配列はコピーできない

前提知識、配列は配列で初期化できない

前提知識、ポインタならコピーできる

コピーできると言ってもポインタにアドレスをコピーしているだけ。

前提知識:関数もコピーできない

配列と同様に関数もコピーできないけど、関数へのポインタならコピーできる。

std::decay

こんな事があるので、テンプレートで型を汎用的に扱おうとすると一部の型でできなくなることがある。このできなくなる型の場合にできる型に変換してくれるのがstd::decay

“aaa”というリテラル文字列は型としてchar[4]なのでそのままだと初期化できない。そこでdecayを使ってこれをポインタ型に変えるとコピーできる。

生関数のままの型だとコピーできないのでエラーになるけどdecayを使って関数へのポインタに変換すればコピーできる。

JavaScriptの難しいところ覚書

C++プログラマやJavaプログラマにとってJavaScriptの分かりづらいところを解説。

スコープ

C++では{}で括ったブロックがスコープになるがJavaScriptではスコープにならない。

2つのaは同じaになる。

関数はスコープを持つ

上のコードでfunction内のvarを外すと同じaを参照する。

コンパイルと実行

JavaScriptの実行は2段階で行われる。最初は変数を割り当て、次に実行する。割当時にはどのスコープにどの変数があるかを確定する。varによる変数の宣言や変数への書き込みは割当であり、変数の読み込みは割当処理ではスルーされる。

上記のコードではa,b,cは割当時に割り当てられるが、dは割り当てられないので実行時にエラーになる。cは書き込み処理なので割当時に割り当てられる。cでもエラーにしたい場合はファイルの最初に"use strict"(ダブルクオーテーション含む)と記述する。

オブジェクトと辞書

オブジェクトと辞書は同じ。

Objectは実際は関数である(後述)。

関数とオブジェクト

JavaScriptにはクラスがない。クラスのようなものをつくりたいときは関数で行う。

newを使うと、空のオブジェクトをつくりそれを暗黙の引数として渡す。関数内ではthisとして参照しそのオブジェクトを返す。

this

C++と同じようにオブジェクトのメンバ関数をコールすると暗黙の引数thisが渡される。

getasetaではthisを参照しているので関数を呼び出したオブジェクトがthisになりその値が変わる。

getcsetcではthisを参照していないのでオブジェクトは変更されない。そもそもこのcはオブジェクトに含まれてはおらず関数funcが持っている変数である。getcsetcはそのcを参照するがstaticでもなく、newでオブジェクトがつくられるごとにつくられそれが参照されている。よってcはオブジェクトがもつprivate変数のように扱える。

ここでnewを使わずにfuncをコールするとthisWindowオブジェクトになる。このオブジェクトは実行環境で変わり、ブラウザ上ではWindowオブジェクトになる。グローバルに宣言された変数はこのWindowオブジェクトのプロパティになっている。

prototypeと__proto__

関数はprototypeメンバとしてObjectをもつ。この関数でnewしてつくられたオブジェクトは__proto__メンバをもち同じObjectをもつ。

オブジェクトのプロパティを参照するとき、そのプロパティが見つからなかった場合は、__proto__から探す。よって関数のprototypeにあるプロパティを持たしておくと、オブジェクトで共通のプロパティを持つことができる。

prototype自体もオブジェクトでObjectは関数なのでprototype__proto__をもつ。よってあるプロパティを参照してそれが見つからないとき__proto__から見つけようとするがそれもないときは__proto__.__proto__から見つけようとする。よってObject.prototypeにプロパティを設定しておくとすべてのオブジェクトで共通のプロパティを持つことができる。

Object.prototype__proto__nullになっているので無限ループにはならない。

Windows10でsvchost.exeのグループ化する

svchostとは

svchost.exeはサービスを提供する実行ファイル、サービスとはユーザがサインインしていなくてもバックグラウンドで動いているプロセス。Windows10のCreators Update (version 1703)からサービス1つにつき1プロセスで起動(分割サービス)するようにしたため多くのサービスがタスクマネージャなどに表示される。ただしこれは常に行われるわけではなくメモリのサイズが3.5Gより大きければ分割サービスになる。3.5G以下の場合は以前のWindowsのようにサービスがグループ化される。グループ化といってもすべてのサービスが1つのプロセスで実行されるわけではなくある程度は分けられる。

分割サービスによりいくつかの利点がある。

  • プロセスで分けられているため1つのサービスに不具合があってもだのサービスに影響しない。
  • 特権などはプロセスごとに持つため設定しやすくなる。
  • CPUの使用率を制限するときもプロセス単位なのでやりやすくなる

ただし、プロセスをたくさん起動するとメモリ効率は悪くなるので、ここでは分割サービスになっているシステムをグループ化に戻す方法を紹介する。

分割サービスの状態:多くのサービスがある

manysvchost
Taskmanager shows many svchost.exe processes

8Gでサービスをプロセスに分けるように設定

レジストリキー:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SvcHostSplitThresholdInKBの値を8Gで設定する。実際の値はキロバイトなので、8388608になる。( = 8 * 1024 * 1024 )

svchost-split-from-8g
The value of the highlighted item is set 8G, if the actual memory is above this value, services will be splitted.

再起動すると反映される。

サービスがグループ化される

svchosts are grouped

サービスがグループ化されてsvnchost.exeの数が減った。

プロセスが実行しているサービスを確認する

Process Explorerでできる。svchost.exeをダブルクリックしてから’Services’タブを表示すると以下のようにサービスの一覧が表示される。

参考リンク

Changes to Service Host grouping in Windows 10

[Windows 10 Fix] Why Too Many Svchost.exe (Service Host) Process Running in Task Manager

chrome ver 69で形の変わったタブを元に戻す

Google chromeがversion69になるとタブの形が変わって以下のようになる。

chrome69-newtab

元に戻す

オムニボックス(アドレスバー)に以下を入力。

chrome://flags/#top-chrome-md

以下のように、UI Layout for the browser’s top chromeをNormalに変える。変更後Chromeを再起動すると元に戻る。

一度だけ初期化する処理をstaticとラムダで行う(C++)

以下のソースはある機能が利用可能かの状態を返す。一度だけ初期化するのでstaticとラムダ関数で行っている。

最初に呼ばれたときはラムダ関数を実行し、次からはstatic変数の値を返す。

ラムダ式

ラムダ式の戻り値はreturnから自動で推論される。この場合はboolになる。

スレッド

C++11でstatic変数のスレッドセーフが保証されたので、上記ラムダ式が2度動くことはない。

ソースコード

https://github.com/ambiesoft/blogprogs/tree/master/5075/src

Qt CreatorでQtのソースコードにステップ・インする

Qtソースコードをインストールする

Install Qt source code
Install Qt source code

Qt Creatorでソースコードのパスを設定する

設定するパスは{QtInstallDir}\Qt\5.11.0\Srcになる。

Add Qt source code directory
Add Qt source code directory

Qt Creatorでデバッグしてステップ・インする

これでQtのソースコードにステップ・インすることができる。Qtのソースコードにブレークポイントを設定することもできる。

サンプルソースコード

ソースコード