为#define使用变量

Using a variable for #define

本文关键字:变量 #define      更新时间:2023-10-16

Libcurl使用以下内容来定义电子邮件收件人:

#define RECIPIENT "<bla@bla.com>"

但是如果我不想硬编码收件人呢?我希望用户能够提供他/她自己的电子邮件地址,所以我需要找到一种方法来做到这一点:

std::string emailreceiver = "bla@bla.com";
#define RECIPIENT = emailreceiver

收件人用于以下行:

rcpt_list = curl_slist_append(rcpt_list, RECIPIENT);

我想我不能简单地将其更改为

std::string emailreceiver = "bla@bla.com";
rcpt_list = curl_slist_append(rcpt_list, emailreceiver);

有人有什么建议吗?

Curl需要一个C字符串(const char *(,而不是C++字符串(std::string(。所以试试:

std::string emailreceiver = "bla@bla.com";
rcpt_list = curl_slist_append(rcpt_list, emailreceiver.c_str());

根本不需要使用#define,这只是一个例子。

您的最后一个片段可能非常接近。从外观上看,curl需要一个C风格的字符串,所以可能必须将其更改为:

std::string emailreceiver = "bla@bla.com";
rcpt_list = curl_slist_append(rcpt_list, emailreceiver.c_str());

libcurl并没有真正做到这一点。问题中的#definedocs/examples/smtp-multi.c:中的一行最为相似

#define RECIPIENT "<recipient@example.com>"

宏只使用一次,稍后在同一源文件中使用:

rcpt_list = curl_slist_append(rcpt_list, RECIPIENT);

(引用的行来自curl版本7.23.0。(

正如文件名所暗示的,这只是一个例子。在实际应用程序中,您不太可能希望使用硬连接的宏作为收件人名称。

curl_slist_appendcurl.h中的声明为:

CURL_EXTERN struct curl_slist *curl_slist_append(struct curl_slist *,
                                                 const char *);

(现在不要担心CURL_EXTERNconst。(

因此,当您调用curl_slist_append时,第二个参数必须是char*。特别是,它可以是字符串文字,可以直接在调用中编写,也可以是宏扩展的结果。但它可以是char*类型的任何表达式,只要它指向一个有效的字符串。

您需要决定如何确定收件人电子邮件地址,并将指向该字符串的指针(C样式字符串,而不是C++std::string(作为curl_slist_append的第二个参数。为此目的使用宏可能没有意义。这只是示例程序演示正在发生的事情的一种简单方法

至于你在评论中的问题:"我仍然很好奇是否可以将变量分配给#define。"——好吧,是和否。你不会将任何东西分配给#define#define(宏定义(是一种编译时构造,它会导致宏名称的任何出现都被宏定义的文本替换。例如:

#define RECIPIENT "<recipient@example.com>"
rcpt_list = curl_slist_append(rcpt_list, RECIPIENT);

与此完全等效:

rcpt_list = curl_slist_append(rcpt_list, "<recipient@example.com>");

(除了后者没有定义RECIPIENT(。如果将宏定义从"<recipient@example.com>"更改为您喜欢的任何其他内容,则每次出现的RECIPIENT都将被您在#define RECIPIENT之后编写的内容所替换。

所以你可以这样做:

char *recipient = get_recipient();
#define RECIPIENT recipient
rcpt_list = curl_slist_append(rcpt_list, RECIPIENT);

但没有真正的意义;你不妨写下:

rcpt_list = curl_slist_append(rcpt_list, recipient);

预处理器(编译器中处理#define指令和宏扩展等的部分(对函数调用、变量和类似结构完全一无所知。它只是进行文本替换,而不考虑文本的含义。(它实际上是根据令牌定义的。(

这意味着您可以滥用预处理器来做一些危险的事情。下面是一个例子。