Using a variable for #define
Libcurl uses the following to determine the email recipient:
#define RECIPIENT "< bla@bla.com >" But what if I don't want to hard code the recipient? I want the user to be able to provide their own email address, so I need to find a way to do this:
std::string emailreceiver = " bla@bla.com "; #define RECIPIENT = emailreceiver The recipient is used on this line:
rcpt_list = curl_slist_append(rcpt_list, RECIPIENT); I guess I can't just change this to
std::string emailreceiver = " bla@bla.com "; rcpt_list = curl_slist_append(rcpt_list, emailreceiver); Anyone have any suggestions?
libcurl does not actually do this. #define in your question most closely resembles the line in docs/examples/smtp-multi.c :
#define RECIPIENT "< recipient@example.com >" The macro is used exactly once, later in the same source file:
rcpt_list = curl_slist_append(rcpt_list, RECIPIENT); (Quoted lines from curl version 7.23.0.)
As the name of the file suggests, this is just an example. In a real application, it is unlikely that you will want to use a hard IP address for the recipient name.
The curl_slist_append , in curl.h :
CURL_EXTERN struct curl_slist *curl_slist_append(struct curl_slist *, const char *); (Donβt worry about CURL_EXTERN or const ).
Therefore, when you call curl_slist_append , the second argument should be char* . In particular, it can be a string literal, either written directly in the call, or the result of macro expansion. But it can be any expression of type char* if it points to a valid string.
You need to decide how you want to determine the recipient's email address, and pass a pointer to this string (C-style string, not C ++ std::string ) as the second argument to curl_slist_append . It probably doesn't make sense to use a macro for this purpose. It was an easy way for an example program to demonstrate what was happening.
As for your question in the comment: "I'm still wondering if you can assign the variable #define or not." - Well, yes and no. You do not assign anything to #define . A #define (macro definition) is a compile-time construct that forces any occurrence of the macro name to be replaced by the literal text of the macro definition. For example, this:
#define RECIPIENT "< recipient@example.com >" rcpt_list = curl_slist_append(rcpt_list, RECIPIENT); exactly equivalent to this:
rcpt_list = curl_slist_append(rcpt_list, "< recipient@example.com >"); (except that the latter does not leave RECIPIENT ). If you change the definition of the macro from "< recipient@example.com >" to whatever you like , then every occurrence of RECIPIENT will be replaced by everything you wrote after #define RECIPIENT .
So you can do something like this:
char *recipient = get_recipient(); #define RECIPIENT recipient rcpt_list = curl_slist_append(rcpt_list, RECIPIENT); but there is no real point; you could just write:
rcpt_list = curl_slist_append(rcpt_list, RECIPIENT); The preprocessor (a piece of compiler that processes #define directives and macro extensions, by the way) has absolutely no idea about function calls, variables, and similar constructs. It is just a text replacement without regard to what the text means. (In fact, this is defined in terms of tokens.)
This means that you can abuse the preprocessor to do some dangerous things. Here is an example.