2017-07-27 16 views
0

ルックアップマクロを作成しようとしています。三項演算子を使うことは、これを行うための非常に簡潔な方法のようです。ここで私がこれまで持っているものです。マクロ拡張3進ルックアップテーブル

#define SQL_LOOKUP_TABLE(x) (strncmp(x, "int", strlen(x)) == 0) ? "INTEGER" : SQL_LOOKUP_TABLE1(x) 
#define SQL_LOOKUP_TABLE1(x) (strncmp(x, "char", strlen(x)) == 0) ? "TEXT" : SQL_LOOKUP_TABLE2(x) 
#define SQL_LOOKUP_TABLE2(x) (strncmp(x, "double", strlen(x)) == 0) ? "REAL" : "" 

は、私はC言語で文字列としてタイプを渡し、その後、対応するSQL文字列として型バック取得したいです。 、私は本当に何をしたいのか

printf("Ternary test: %s\n", SQL_LOOKUP_TABLE("double")); //output "REAL" 

この情報を取得し、全体のSQLのCRUDステートメントを構築である:それは私がこのような何かをしたときに素晴らしい作品。この問題は、別のマクロの内部に文字列を作成しようとすると発生します。このような何かが動作しません:

#define BUILD_A_STRING(x) "CREATE TABLE (" SQL_LOOKUP_TABLE(x) 

私が取得エラー:

error C2064: term does not evaluate to a function taking 337 arguments 

クイックノートで、これは動作しません(リターンを "REAL"):

#define BUILD_A_STRING(x) SQL_LOOKUP_TABLE(x) 

任意のアイデアなぜ私ができます別のマクロの中でマクロを呼び出したり、文字列を作成したりすることはできません。

編集(TMIを提供するリスクのある): これは私が本当に何をしたいです:

typedef struct { 
    double yomama; 
    int x; 
    char shiboopy[100]; 
} test_data1; 

#define EXPAND_AS_CREATE_STATEMENT(type, element, struct_name) SQL_LOOKUP_TABLE(#type) " " # element ", " 
#define test_data1_TABLE(ENTRY)  \ 
    ENTRY(double, yomama, test_data1)   \ 
    ENTRY(int, x, test_data1) \ 
    ENTRY(char, shiboopy, test_data1) 
char* create_stmt = "CREATE TABLE test_data1 (" test_data1_TABLE(EXPAND_AS_CREATE_STATEMENT) ");"; \ 

は、基本的に何でもCRUDにそれを展開し、構造体のデータ型を定義するためにXマクロを使用し、私が必要とするかもしれない陳述。

+0

どのように 'BUILD_A_STRING'を使用しようとしていますか? –

+0

あなたのコンパイラには、前処理のみを行うオプションがあり、展開を見ることができます。それを試してみて.....そして、なぜ機能を作るだけではないのですか?マクロを使用すると、多くの場合、exeファイルが膨大になることがあります。 –

+1

'337個の引数をとる関数に評価されない 'は、何とか閉じ括弧を緩めてしまったことを伝えます。 – Serge

答えて

1

私はこの解釈だ

I want to pass in the type as a string in c, and then get the corresponding SQL type back as a string.

私はあなたを考えていませんタイプはのC文字列として渡す必要があります。その文字列でやっていることは、マクロに直ちに渡すことです(マクロは文字列で何もできません)。代わりに、トークンをマクロに渡すと、Cプリプロセッサ自身がルックアップを行うことができます。ここで

が私の意味は次のとおりです。

#define EXPAND_AS_CREATE_STATEMENT(type, element, struct_name) \ 
    SQL_LOOKUP_TABLE(type) " " # element ", " 

...と、この:

"CREATE TABLE test_data1 (" test_data1_TABLE(EXPAND_AS_CREATE_STATEMENT) ");" 

#define SQL_LOOKUP_TABLE(x) DB_TYPE_FOR_ ## x 
#define DB_TYPE_FOR_double "REAL" 
#define DB_TYPE_FOR_int  "INTEGER" 
#define DB_TYPE_FOR_char "TEXT" 

このマクロにトークンを渡し、ないトークンを文字列化

...これに展開する:012文字列リテラルの連結後に相当し

"CREATE TABLE test_data (" "REAL" " " "yomama" ", " "INTEGER" " " "x" ", " "TEXT" " " "shaboopy" ", " ");" 
...:

"CREATE TABLE test_data (REAL yomama, INTEGER x, TEXT shaboopy,);" 

ませんstrcmp年代は、三元系のないチェーンは、何のハッシュテーブルは必要ありません。今、私は、あなたのデータベースエンジンがパラメータリストの末尾にカンマを受け入れるほど怠惰であるかどうかは分かりませんが、それは別の問題です(最も簡単な解決策はXマクロに区切りマクロを追加することです)。

+0

文字列化されたトークンではなく、トークンを渡すことが、私のXマクロで完璧に機能しました! – Galactasm

2

字句文字列連結は、プリプロセッサ操作です。三項演算子はランタイム演算です。文字列が連結されようとしているときに、プリプロセッサは、隣接する文字列リテラルを探しますが、

"CREATE TABLE (" SQL_LOOKUP_TABLE(x) 

"CREATE TABLE (" (strncmp(x, "int", strlen(x)) == 0) ? "INTEGER" : SQL_LOOKUP_TABLE1(x) 

に前処理され、プリプロセッサを約strncmpを知らないので、いずれかを見つけることに失敗します、strlen、または3項演算子。

プリプロセッサを実行するときに条件付きの処理を行う必要があります。 Cプリプロセッサはあまりにも単純ですが、m4のようなより高度なプリプロセッサが必要です。
他の悪い方法は、明らかに少しのオーバーヘッドを伴う実行時に連結を行うことです。

デザインを再考することをおすすめします。ハッシュテーブルが便利になるかもしれません:それはうまくいくでしょうし、より洗練され、より効率的です。

0

@Downvoterの答えはあなたが得るエラーの理由を説明しています。 あなたのケースでは関数を使う方が良いと思います。以下のような 何か:

char* build_str(char* type) 
{ 
    static char str[80]; 
    char* sql_type_str = SQL_LOOKUP_TABLE(type); 
    strcat(str, "CREATE TABLE ("); 
    strcat(str,sql_type_str); 
    /* strcat others params */ 
    return str; 
} 

はたぶん、あなたは、あなたがBUILD_STRINGを使用する予定の方法についての詳細を与える必要があります。これをオーバーライドするよう...

This is what I really want to do:

What I really want to do, is take this information and build an entire SQL CRUD statement.

...と、この:

関連する問題