user285594
user285594

Reputation:

C++ - why is this code not working when a macro is used?

When I use the a->url inside a macro then it's failing, but when I replace a->url and put the string in manually it works. How do I make a->url compatible with the macro?

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;  
}

Upvotes: 0

Views: 336

Answers (2)

Your macro expands to this:

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

which is obviously not valid.

Upvotes: 5

Ryan Haining
Ryan Haining

Reputation: 36802

(Note remove the ; at the end of the macro definition)

If you run g++ -E you can see the output of the preprocessor. #defines are just text replacement, so when you have

MANIFEST_URL(a->url)

it will expand to

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

The intention of this macro is obviously to be used with a string literal, and if you do so:

MANIFEST_URL("www.google.com")

It expands to

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

adjacent string literals are concatenated by the compiler, so the above is equivalent to

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

If you want this to work with std::string or c string char* identifiers, just define a function to do so:

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

Upvotes: 4

Related Questions