プログラミング」カテゴリーアーカイブ

Visual C++ での C99 complex

最近のVisual C++ではC99もある程度サポートしているらしい。

上記ブログによると、 complex.h の関数もサポートしているらしい。しかし、コンパイラーは _Complex 型をサポートしていない。_Complex 型をサポートしていないのに、 complex.h の関数をサポートしているとはどういうことか。一体、 complex.h の関数は何を受け取って何を返すのか。

確認のため、次のような簡単な C++ のプログラムを書いてみた。 続きを読む

wxWidgets をビルドする

wxWidgets とは、C++で作られたクロスプラットフォームGUIツールキットである。Windows, OS X, GTK+ などに対応している。商用版のある Q なんとかと比べて見劣りするとか言うんじゃないぞ

入手

開発中の最新版を入手しよう。wxWidgets のリポジトリは、現在 GitHub でホストされている。(ただし、Issue の管理は GitHub ではなく wxWidgets Trac を使っている。GitHub でのプルリクはできる)

https://github.com/wxWidgets/wxWidgets

続きを読む

C言語でなんちゃって2進数リテラル

こういうビットマップ(1ピクセルにつき1ビット)を、整数の配列としてC言語のソースコード中に埋め込みたい:

□□□□□
■■■■■
□■□■□
□■□■□
■□□■■
□□□□□

2進数リテラルがあればそれを使うという手があるが、残念ながらC言語には2進数リテラルがない(ちなみに、C++にはC++14から2進数リテラルが入った。また、独自拡張で2進数リテラルが使えるコンパイラーもある)。

というわけで、自分で作ることにした。要件としては

  • コンパイル時定数となる
  • 桁を空白で区切れる

がある。 続きを読む

C言語の可変長引数マクロで擬似オーバーロード

C99で導入されたプリプロセッサマクロの可変長引数を使って、引数の個数によるオーバーロードっぽいことをするメモ。

参考:

可変長引数の部分への実引数が0個というのはC言語の規格的にはナシなので、引数が0個の場合には対応しない。(幾つかのコンパイラでは引数が0個でも通るが…)

GCCの場合に0個の引数を処理したい場合、GCC拡張の , ## __VA_ARGS__ みたいなやつを使うといい感じになる。

VC++で

#define CHOOSE(a0,a1,...)
#define hoge(...) CHOOSE(__VA_ARGS__)

という風に書くと、 __VA_ARGS__ の部分が一つの引数(a0)として関数型マクロに渡ってしまうので、ここに書いたコードでは CHOOSECHOOSE2 という風にもう一段階噛ませている。

C11の _Generic とかを使えば引数の型によるオーバーロードもできそうだ。先例:

JavaScript近代史

先月はECMAScript 2015 (ECMAScript 6)が採択され、また、WebAssemblyが発表された。多分これらは現代のWebプログラミング言語の歴史に残る出来事だろう。しかし、ここ10年ぐらいのJavaScript/ECMAScriptの歴史と背景事情みたいのをまとめた文章のようなものをあまり見かけないので、ちょっとだけ書いてみることにする。(というよりは「ちょっとだけ調べてみた」の方が適切。あんまりまとまってないし)

続きを読む

Macの受信メールから自動でリマインダーを作成する

何日までに○○しなさいというメールが届いた!けどほったらかしておいたら期限を過ぎていた!そういう経験、あるよね?

library-mailそこで、そういうメールが届いたら自動でMacの「リマインダー」に登録されるようにしよう!という話。
続きを読む

TypeScript 1.5でのlet文

ECMAScriptの変数のスコープが不思議な挙動をするのはよく知られた話だ。ECMAScript 5での変数のスコープは以下のいずれかに大別される(はず)。ブロックスコープがない。

  • グローバルスコープ
  • 関数スコープ
  • catchスコープ

普通に使う変数が関数スコープしかないのは不便、ということで、MozillaはJavaScript 1.7(2006年頃)でlet文を導入した。が、しかし、他のブラウザには普及せず、Mozillaの独自拡張に留まることになった。

時は過ぎ、ECMAScript 5が制定され、次はECMAScript 6という流れになってきた。そして、ECMAScript 6にはlet文が導入されることになった(MozillaがJavaScript 1.7で導入したものとは微妙に仕様が違う)。めでたしめでたし。

ECMAScriptに静的型を付けたTypeScriptは、当初はlet文をサポートしていなかった。それが、TypeScript 1.4で、ECMAScript 6へコンパイルする場合のみlet文をサポートするようになった。

が、ECMAScript 6(のlet文)に対応していないブラウザはまだまだたくさんある(今調べてみたら、IE11ではES6のlet文に対応しているけど、Safariでは対応していないようだ)。できれば、TypeScriptのようなaltJS言語でlet文を使いつつ、コンパイル後のJavaScriptでは従来のvarを使ってほしい。

が、let文を従来のJavaScript (ECMAScript 5)に変換するのはそう自明なことではない。特に問題になるのは、ループ内の変数を、ループの外に持ち出される関数で使っている場合だ。[code lang=”js”]
var a = [];
for (var i = 0; i < 5; ++i) {
let x = i * i;
a.push(function() { return x; });
}
[/code]上のコードを下のように単純にvarを使うと挙動が変わってしまう。[code lang=”js”]
var a = [];
for (var i = 0; i < 5; ++i) {
var x = i * i;
a.push(function() { return x; });
}
[/code]このコードを正しくECMAScript 5に翻訳するには、即時実行関数(IIFEを使って以下のようにしなければならない。[code lang=”js”]
var a = [];
for (var i = 0; i < 5; ++i) {
(function() {
var x = i * i;
a.push(function() { return x; });
}());
}
[/code]こういう非自明、というかパフォーマンスに影響するところがあるので、TypeScript 1.4ではES5へのコンパイル時にlet文がサポートされなかったのだろう。

が、しかし、TypeScript 1.5ではES5へコンパイルする場合でもlet文が部分的にサポートされるようになるようだ。「部分的に」というのは、ループが絡まない、変数のスコープのチェックと名前の変更で済む場合、のようだ。[code lang=”js”]
{
let x = 123;
console.log(x); // OK
}
console.log(x); // エラー
[/code]
ループが絡む、IIFEを使った変換が必要な場合は、

test2.ts(2,1): error TS4091: Loop contains block-scoped variable 'x' referenced by a function in the loop. This is only supported in ECMAScript 6 or higher.

というエラーが出た。
[code lang=”js”]
let a: Array<() => number> = []
for (var i = 0; i < 5; ++i) {
let x = i*i;
a.push(() => x);
}
a.forEach(console.log);
[/code]

GitHubでの該当するIssue/Pull Requestは以下のようだ。

let文のサポートとしては不完全とはいえ、varの関数スコープのせいで意図しない同名の変数を参照していた〜〜みたいな事故は防げると思われるので、積極的に使っていきたい。

Idrisの有界な自然数で遊んでみる(1) — 証明をつける

前回:Idrisの有界な自然数で遊んでみる(0)

前回はIdrisで「有界な自然数の冪乗を計算する」finPower2 : Fin n -> Fin (power 2 n) という関数を実装したが、いくつか後回しにした証明があった。今回はIdrisの証明支援機能を使ってこれを埋める。

続きを読む

Idrisの有界な自然数で遊んでみる(0)

プログラミング言語Idris自体についての詳しい話はここではしない。このブログの昔の記事で軽く紹介したかもしれないが他人の参考になるかは分からない。

この記事を読むにあたっては、

  • ペアノ算術

は知ってないと厳しいと思われる。あとHaskell風の言語にも慣れていた方がいいか。

この記事で使うIdrisのバージョンは0.9.16である(執筆時点の最新版)。これと異なるバージョンだとコードの修正が必要かもしれない。

続きを読む