2016-05-10 15 views
6

この問題を解決するのを手伝ってください。これは、Cで行番号、ファイル名、var argsを取得するためのサンプルコードです。これを実行しようとすると、いくつかのエラーが発生しました。私はこれを行う多くの方法があると確信しています。しかし、私はいくつかの機能を達成するために既存のコードを使用しなければなりません。どんな助けや提案も大歓迎です。マクロ内のマクロC

#include <stdio.h> 
#include <stdlib.h> 
#include <stdarg.h> 

#define MY_MACRO1(fmt, args...)    \ 
{            \ 
    char buf_d[1024];      \ 
    MY_MACRO2(__FILE__, __LINE__,call_func(buf_d,sizeof(buf_d),fmt,##args)); \ 
} 

#define MY_MACRO2(__FILE__, __LINE__,fmt, ...) printf("%s : %d -> %s : \n",__FILE__, __LINE__, __VA_ARGS__); 

char * call_func(char *buf_t, size_t size, const char *fmt, ...) 
{ 
    va_list ap; 
    va_start(ap,fmt); 
    vsnprintf(buf_t, size, fmt, ap); 
    va_end(ap); 
    return buf_t; 
} 


int main() 
{ 
    printf("\n Now I am printintg macro....\n"); 
    MY_MACRO1("Macro is working fine..\n"); 
    return 0; 
} 

出力:

マクロ展開を見つけてください。マクロの最後の引数(funcの戻り値)がありません。

char buf_d[1024]; 
printf("%s : %d -> %s : \n","file.c",35,);; 

エラー:

file.c:35:83: error: expected expression 
{ char buf_d[1024]; printf("%s : %d -> %s : \n","file.c", 35,);; }; 
                  ^

1エラーが発生しました。

+3

象:なぜマクロを使用しますか? – user4581301

+3

デュアルタグの理由はなぜですか?あなたは、質問で指定していないコンパイラの非標準コンパイラ拡張を使用しています。それは有効なCになる必要がありますか?それは有効なC + +になる必要がありますか?それはあなたの特定のコンパイラに受け入れられる必要がありますか? 3つすべてがあなたに異なる答えを与えるでしょう。そしてなぜ地球上で '__FILE__'と' __LINE__'をマクロパラメータとして再定義するのを選ぶのですか? – hvd

+0

IIRC 'fmt、args ...'後に '、## args'が続くのは移植不可能な拡張です。 'fmt、args ...'と '__VA_ARGS__'の代わりに' fmt、## args'の代わりに '...'を使うことができます。 – technosaurus

答えて

1

, ...を使用すると、引数を指定する必要がありますが、これはあなたのケースではありません。引数リストに名前をつけてマクロを変更し、必要に応じてプリプロセッサにカンマを忘れさせることができます。

#define MY_MACRO1(fmt, args...)    \ 
{            \ 
    char buf_d[1024];      \ 
    MY_MACRO2(__FILE__, __LINE__,call_func(buf_d,sizeof(buf_d),fmt,##args)); \ 
} 

#define MY_MACRO2(F,L,fmt,args...) printf("%s : %d -> %s : \n",F, L, fmt, ##args) 
+0

test_macro.c:30:2:警告:データ引数よりも多くの '%'変換[-Wformat] 私はあなたが正しいと思います。しかし、私が試したとき、私は次の警告を受け取りました。それは、希望の文字列の代わりにいくつかのガベージを印刷しています..test_macro.c:20:69:メモ:マクロ 'DEBUG_APMD_V2'から展開 #define DEBUG_APMD_V2(file、line、fmt、args .. 。)printf( "%s:%d - >%s:\ n"、ファイル、行、## args); 〜^ 警告が生成されました。 – Rock26

+0

あなたの例は、私のために作品を提案したように変更されました、あなたの実際の状況は少し異なるでしょうか? –

+2

省略記号の前にカンマなしの表記は、GCC(および恐らくGCC互換のClang)拡張であることに注意してください。 –

2

のは、物事をきれいにしましょう:

をコード:

#include <stdio.h> 
#include <stdlib.h> 
#include <stdarg.h> 


#define DEBUG_MSG(_msg, ...) do {print_debug_msg(__FILE__, __LINE__, __FUNCTION__, _msg, ## __VA_ARGS__); }while(0) 


void print_debug_msg(const char * module, int line, const char * func, const char * fmt, ...) 
{ 
    va_list va; 
    char buf[ 1024 ] = {0}; 

    va_start(va, fmt); 
    vsnprintf(buf, sizeof(buf), fmt, va); 
    va_end(va); 

    printf("%s:%d - %s() - %s\n", module, line, func, buf); 
} 


int myfunc(const char * msg) 
{ 
    DEBUG_MSG("Message: %s", msg); 

    return 0; 
} 


int main(int argc, char * argv[]) 
{ 
    DEBUG_MSG("The quick brown fox jumps over the lazy dog."); 

    DEBUG_MSG("Pack my box with five dozen liquor jugs."); 

    myfunc("How vexingly quick daft zebras jump"); 

    myfunc("The five boxing wizards jump quickly."); 

    return 0; 
} 

/* eof */ 

コンパイル:

$ gcc -Wall macro.c -o macro 

テスト:

$ ./macro 
macro.c:32 - main() - The quick brown fox jumps over the lazy dog. 
macro.c:34 - main() - Pack my box with five dozen liquor jugs. 
macro.c:24 - myfunc() - Message: How vexingly quick daft zebras jump 
macro.c:24 - myfunc() - Message: The five boxing wizards jump quickly. 

参考文献:

1) Recommended C Style and Coding Standards (Macros)

2) GCC Manual - Standard Predefined Macros

希望に役立つ!