2011/3/5 - 2011/7/29
Pen Jr.D言語なんてやってみそWelcome Beginner
プラグマ( Pragmas
pragma( 識別子 );
pragma( 識別子, ArgumentList );
コンパイラ へ特別な情報を渡したり、 言語 の拡張を追加するための・・・

ちょっと特殊な Keyword です。

msg
定義済みプラグマで、コンパイル中 にメッセージを表示します。
pragma( msg, ... );
コンパイルされると、msg の後の引数が表示されます。
import std.stdio;

void main(){
  // コンパイル メッセージ
  pragma(
    msg,
    "Welcome Beginner\n", " by pragma msg"
  );
  // 実行メッセージ
  writeln(
    "Welcome Beginner\n", " by writeln"
  );
}

コンパイルして実行

D:\Pen-Jr\My Programs\types>dmd test
Welcome Beginner
 by pragma msg

D:\Pen-Jr\My Programs\types>test
Welcome Beginner
 by writeln

実行時には無関係で、コンパイル時に決まる 定数 に限りますが、ほとんど writeln と同じ様に使えます。

-c 指定コンパイル
pragma は組み込みですから import が不要で、実行する必要もありませんから エントリーポイント が必要ありません。

コンパイル時に -c を指定すれば、コンパイルだけで実行ファイルは作りませんから、

軽量モジュール を、

  /*
  ^   import も main関数もなし
  ^
  ^     これだけでコンパイル
  */
pragma(
  msg,
  "Welcome Beginner\n", " by pragma msg"
);

-c を付けてコンパイル。

D:\Pen-Jr\My Programs\types>dmd test -c
Welcome Beginner
 by pragma msg

オブジェクトファイル( test.obj )だけ出力して、終了します。

指定なしでコンパイルすると、

D:\Pen-Jr\My Programs\types>dmd test
Welcome Beginner
 by pragma msg
OPTLINK (R) for Win32  Release 8.00.8
Copyright (C) Digital Mars 1989-2010  All rights reserved.
http://www.digitalmars.com/ctg/optlink.html
OPTLINK : Warning 23: No Stack
OPTLINK : Warning 134: No Start Address

リンカー に叱られます。

コンパイル中のメッセージで何すんの?
メタプログラム のデバッグなんかには使いますが、実行時には関係ないですからほとんど出番はありません。
リアルな言語仕様
言語仕様はリファレンスだけでなく、コンパイラに直接聞いて調べることが出来ます。

その場合も、pragma でなければ得られないようなことはほとんどなく、また pragma ではコンパイル時に決まる情報以外は得られません。

実行させる手間など知れてますし、実行させた方がより多彩な方法で調べることも出来ますが、型 などの言語仕様を見る時には、あえて使う意味もあります。

  • 実行時の writeln などの仕様に依存しない。
  • 確実に「コンパイル時に決まる定数」だけになる。
  • 通常のサンプルコードとの差別化が出来る。
  • 組み込みならでは表示がうれしい。
2進数( Binary )
プログラミング相手(CPU)の思考は2進数です。
整数リテラル( Integer Literals
リテラルで 10進数 以外の表記が出来ます。
  /*
  !   -c 指定でコンパイル
  */
pragma(
  msg,
  "10   = ", 10,
  /*
  *   2進数
  *     0b か 0B で始まり 0 か 1
  */
  "\n0b10 = ", 0b10,
  /*
  *   16進数
  *     0x か 0X で始まり
  *     0..9 と a..f、A..F
  */ 
  "\n0x10 = ", 0x10,
  //
  "\n\n1_0_0    = ", 1_0_0,
  "\n0b1_0_0  = ", 0b1_0_0,
  "\n0B_1_0_0 = ", 0B_1_0_0,
  "\n01_0_0   = ", 01_0_0,
  "\n0_1_0_0  = ", 0_1_0_0,
  "\n0x1_0_0  = ", 0x1_0_0,
  "\n0X_1_0_0 = ", 0X_1_0_0,
  
  // 16進数は 0-9 と a-f、 A-F
  "\n\n0xabcdef   = ", 0xabcdef,
  "\n0xABCDEF   = ", 0xABCDEF,
  "\n0XaB_cD_eF = ", 0XaB_cD_eF
);

-c 指定でコンパイル

D:\Pen-Jr\My Programs\types>dmd test -c
10   = 10
0b10 = 2
010  = 8
0x10 = 16

1_0_0    = 100
0b1_0_0  = 4
0B_1_0_0 = 4
0x1_0_0  = 256
0X_1_0_0 = 256

0xabcdef   = 11259375
0xABCDEF   = 11259375
0XaB_cD_eF = 11259375
pragma でも数値は10進数表示。

ビット処理にも 2進数表記 はほとんど使われず 16進数表記 されます。

0 で始まる 8進数表記 というのもありましたが、v2.054 からなくなりました。
こんぴゅーたー の基本は 永遠 に 2進数(たぶん)
512 やら 1024 のメモリーだとか、4096色表示だとか、半端な数字が多いのは、
import std.stdio, std.conv;

  // 10進数 = 2進数
void toBinary( in int n ){
  writeln(
    n,
    " = ",
    // 値 n を2進数表記(文字列)に変換
    to!string( n, 2 )
  );
}

void main(){
  toBinary( 32 );
  toBinary( 64 );
  toBinary( 512 );
  toBinary( 1024 );
  toBinary( 4096 );
}

これは普通にコンパイルして実行

D:\Pen-Jr\My Programs\types>dmd test

D:\Pen-Jr\My Programs\types>test
32 = 100000
64 = 1000000
512 = 1000000000
1024 = 10000000000
4096 = 1000000000000

最近の大容量 HDD が 3TB とかなのは細かいこと言わなくなったからで、モニターの解像度や Full HD だとかが 2進数 でも半端なのは別の理由からです。

16進数表記
基本は 2進数 ですが、常に 2進数 を意識する必要はありませんから、2進数表記 も必要なさそうですが、

例えば 整数値 は 8, 16, 32 ビットなどで、

import std.stdio, std.windows.charset, std.conv;

  /*----------------------------
  *   UTF8 から Shift-JIS へ変換
  */
string toMBS( in string s ){
  return to!string( toMBSz( s ) );
}

  /*----------------------------
  *   2,16,10 進数で表示する
  */
void toMsg( in int wd, in uint last ){
  writeln(
    wd,
    toMBS( "bit の 0 ~ 0b" ),
    to!string( last, 2 ),   // 2進数表記で
    toMBS( " おば\n16進数でば 0 ~ 0x" ),
    to!string( last, 16 ),  // 16進数表記で
    toMBS( "、 10進数でば 0 ~ " ),
    last,
    toMBS( " だ。" )
  );
}

void main(){
  // bit数を数えやすいよう、2進数リテラルで関数を呼ぶ
  toMsg( 8, 0b1111_1111 );
  writeln();
  toMsg( 16, 0b1111_1111_1111_1111 );
  writeln();
  toMsg( 32, 0b1111_1111_1111_1111_1111_1111_1111_1111 );
}
D:\Pen-Jr\My Programs\types>dmd test

D:\Pen-Jr\My Programs\types>test
8bit の 0 ~ 0b11111111 おば
16進数でば 0 ~ 0xFF、 10進数でば 0 ~ 255 だ。

16bit の 0 ~ 0b1111111111111111 おば
16進数でば 0 ~ 0xFFFF、 10進数でば 0 ~ 65535 だ。

32bit の 0 ~ 0b11111111111111111111111111111111 おば
16進数でば 0 ~ 0xFFFFFFFF、 10進数でば 0 ~ 4294967295 だ。

2進数表記 も大変です。

それぞれの 最大値 を明確に示すのは 2進数表記ですから、最もわかりやすい場合もあるでしょうが、あまりにも冗長で書くにも読むにも面倒です。

また、こういう場合の 10進数表記 はその意味が明確ではありませんし、それぞれに対応する値を憶える必要がありますが、16進数表記 を使えば明確になります。

また、10進数 への暗算には特殊能力が必要ですが、

import std.stdio, std.conv;

  // 16進数 = 2進数
void toBinary( in int n ){
  writeln(
    "0x",
    to!string( n, 16 ),
    " = ",
    to!string( n, 2 )
  );
}

void main(){
  toBinary( 32 );
  toBinary( 64 );
  toBinary( 512 );
  toBinary( 1024 );
  toBinary( 4096 );
  writeln();
  toBinary( 32 - 1 );
  toBinary( 64 - 1 );
  toBinary( 512 - 1 );
  toBinary( 1024 - 1 );
  toBinary( 4096 - 1 );
}
D:\Pen-Jr\My Programs\types>test
0x20 = 100000
0x40 = 1000000
0x200 = 1000000000
0x400 = 10000000000
0x1000 = 1000000000000

0x1F = 11111
0x3F = 111111
0x1FF = 111111111
0x3FF = 1111111111
0xFFF = 111111111111

16進数 への変換なら簡単・・・

もちろん一般的ではありませんから、初めは簡単ではないでしょうが、2進数処理 は 16進数表記 するのが 基本 です。

ほとんどの場合、標準は 10進数表示 ですし、高級言語では 2進数処理 が基本というわけではありませんから、10進数 でのプログラムは問題ありません。

要は「10進数だけで十分」だと、16進数表記 を毛嫌いしないことです。

時に、2進数思考 と 10進数思考 の橋渡しもプログラマーの仕事になりますから。

コードの無効化
書いてはみたけど、思惑通りに動かない・・・だとか、一時的に「プログラムコードの一部を無効にしたい」ということは良く起こります。
コメントアウト
/+ +/
/+
import std.stdio, std.windows.charset, std.conv;

  /*----------------------------
  *   UTF8 から Shift-JIS へ変換
  */
string toMBS( in string s ){
  return to!string( toMBSz( s ) );
}
  /*----------------------------
  *   2,16,10 進数で表示する
  */
void toMsg( in int wd, in uint last ){
  /+
  writeln(
    wd,
    toMBS( "bit の 0 ~ 0b" ),
    to!string( last, 2 ),   // 2進数表記で
    toMBS( " おば\n16進数でば 0 ~ 0x" ),
    to!string( last, 16 ),  // 16進数表記で
    toMBS( "、 10進数でば 0 ~ " ),
    last,
    toMBS( " だ。" )
  );
  +/
}
+/
void main(){
  /+
  // bit数を数えやすいよう、2進数リテラルで関数を呼ぶ
  toMsg( 8, 0b1111_1111 );
  writeln();
  toMsg( 16, 0b1111_1111_1111_1111 );
  writeln();
  toMsg( 32, 0b1111_1111_1111_1111_1111_1111_1111_1111 );
  +/
}
version
E-Mail : open@pen-jr.org

ご意見やご指摘は大歓迎ですが、質問など返信は期待しないでください

pen jr.
D言語研究
わかったつもりになるD言語
D言語友の会
News&Days
はじめてのブログ選び