2017-03-07 4 views
0

マクロ内でa->urlを使用すると失敗しますが、a->urlを置き換えて手動で文字列を入力すると動作します。 a->urlをマクロと互換性を持たせるにはどうすればよいですか?C++ - マクロを使用すると、このコードが機能しないのはなぜですか?

g++ -c -g -std=c++11 -MMD -MP -MF "build/Debug/GNU-MacOSX/main.o.d" -o build/Debug/GNU-MacOSX/main.o main.cpp 
main.cpp:18:35: error: expected ';' after expression 
    cout << MANIFEST_URL(a->url); 

CODE:

#include <iostream> 
#include <ctime> 
#include <string> 
using namespace std; 

#define MANIFEST_URL(REPLACE) "https://" REPLACE "/manifest.json"; 

typedef struct custom { 
    char *id; 
    string url; 
    custom *next; 
} custom; 

int main() { 
    custom *a; 
    a = new custom; 
    a->url = "www.google.com"; 
    cout << MANIFEST_URL(a->url); 
    cout << a->url; 
    return 0; 
} 
+9

マクロ拡張について考えてみましょう。マクロとしてではなく直接書き込んだ場合、本当に有効でしょうか? –

+2

また、前処理は実際のコンパイルとは別の手順であることに注意してください。プリプロセッサは構造体や変数について何も知らない。 –

+3

マクロの代わりに、文字列連結を使用する関数を定義します。 –

答えて

5

注マクロ定義の終わりに;を除く)

あなたがg++ -Eを実行する場合は、プリプロセッサの出力を見ることができます。 #define sがちょうどテキスト置換されているので、あなたが

MANIFEST_URL(a->url) 

を持っている場合には、このマクロの意図は明らかである文字列リテラルで使用されるように、そしてあなたがそうするならば

"https://" a->url "/manifest.json" 

に展開されます:

MANIFEST_URL("www.google.com") 

それは

"https://" "www.google.com" "/manifest.json" 
に展開します個の

隣接する文字列リテラルは、コンパイラによって連結されているので、あなたはこれがちょうどそうする関数を定義し、std::stringまたはC文字列char*識別子で作業したい場合は上記の

"https://www.google.com/manifest.json" 

に相当します。

std::string manifest_url(const std::string& replacement) { 
    return "https://" + replacement + "/manifest.json"; 
} 
6

あなたのマクロは、このように展開:明らかに有効ではありません

cout << "https://" a->url "/manifest.json";; 

関連する問題