- PR -

C++時代の#defineプリプロセッサ

1
投稿者投稿内容
Dr. K
常連さん
会議室デビュー日: 2003/04/26
投稿数: 25
投稿日時: 2003-05-30 16:35
いつもお世話になってます、Dr. Kです。(最近特に)
今回はC#の#define(プリプロセッサ)についての質問です。

古き良きC++時代の#defineではコンパイル時に定数を置き換えてくれるような機能がありました。
例えば、
#define ID_NUMBER 1
#define IDS_STRING "Dr. K"
のように宣言しておいて
printf("%d, %s", ID_NUMBER, IDS_STRING);
ような式をコンパイルするとコンパイル時には
printf("%d, %s", 1, "Dr. K");
と変換してくれて、実行時に発生するエラー(文字列ミスなど)が劇的に減少して非常に便利でした。C#でこれをやろうとするとエラーになります。
しょうがないのでconst文字列を作って強引にやっていますが、これだと余分なメモリを消費してしまいます。(あとで一括置換すればいいし、バグの可能性が増えるよりはましなので、今はこうしてます)
どなたか、C#で上記の式と同等なことが出来る方法をご存知の方がいらしたら是非教えていただけないでしょうか。
Dr. K
常連さん
会議室デビュー日: 2003/04/26
投稿数: 25
投稿日時: 2003-05-30 20:34
自己レスです。

http://www.microsoft.com/japan/msdn/library/default.asp?url=/japan/msdn/library/ja/csref/html/vcwlkconditionalmethodstutorial.asp

でC#コンパイラではマクロをサポートしていないと言っています
ってことはメモリを消費せずに文字列を使うにはリテラルしかないということですね・・・(悲しいなぁ)
横山哲也
大ベテラン
会議室デビュー日: 2001/10/01
投稿数: 163
投稿日時: 2003-05-31 01:36
横山です。

C#は知らないんですが、C++は長いこと使ってましたのでコメントを。

>しょうがないのでconst文字列を作って強引にやっていますが、
>これだと余分なメモリを消費してしまいます。

C++の場合、constは最適化過程によって定数に置換されます。
そのため、左辺値として使わない限りマクロと同じように振る舞うはずです。
少なくとも、プログラマはコンパイラにそう期待します。
左辺値として使う場合も、必要な部分だけメモリを使います。

C#の場合、文字列がオブジェクトなので、どうしても
メモリを使ってしまうということなんでしょうか。

でも、仮想マシンのオーバヘッドの方が大きいような気もしますが。

_________________
Global Knowledge Network
横山哲也
大ベテラン
会議室デビュー日: 2001/10/01
投稿数: 163
投稿日時: 2003-05-31 09:26
訂正

>左辺値として使う場合も、必要な部分だけメモリを使います。

constですから左辺値にはなりません。

参照をする場合も、必要な部分だけメモリを使います。

です。
_________________
Global Knowledge Network
いのつち
ベテラン
会議室デビュー日: 2002/05/14
投稿数: 73
投稿日時: 2003-05-31 10:29
C# でconst 定数値は、コンパイル時にリテラル値にしてコンパイルされます。
リテラルの文字列は、コンパイル時にインターン化されてコンパイルされます。
同じリテラル文字列は、アセンブリ内に1つだけ存在することになります。

だからconstで問題ないと思うのですが・・。

参考文献
 プログラミング.NET Framework (Jeffrey Richter 著)
ISBN4-89100-303-0


Dr. K
常連さん
会議室デビュー日: 2003/04/26
投稿数: 25
投稿日時: 2003-05-31 13:00
引用:

C# でconst 定数値は、コンパイル時にリテラル値にしてコンパイルされます。
リテラルの文字列は、コンパイル時にインターン化されてコンパイルされます。
同じリテラル文字列は、アセンブリ内に1つだけ存在することになります。

だからconstで問題ないと思うのですが・・。

参考文献
 プログラミング.NET Framework (Jeffrey Richter 著)
ISBN4-89100-303-0


たしかに、そう書いてありました。コンパイル時にリテラルになってくれるのであればインターンの機能でメモリの効率は上がりますね。
const文字列がコンパイル時にリテラルになってくれるかという点が不明だったので助かりました。この辺はC++と同じなんですね。(当たり前か。。。)
1

スキルアップ/キャリアアップ(JOB@IT)