我需要使用宏检查我的ipaddr是否等于0.0.0.0。我写了下面的代码,但是不断出错。
#define IPV4_ZEROVAL_CHECK(ip) {int d1,d2,d3,d4; return (4 == sscanf(ip, "%d.%d.%d.%d", &d1, &d2, &d3, &d4)) ? ((d1 == 0 && d2 == 0 && d3 == 0 && d4 ==0) ? 0 : 1) : 0;};
int main()
{
char ip[16] = "0.0.1.0";
int x = 99;
x= IPV4_ZEROVAL_CHECK (ipaddr);
printf("Value of x=%d \n",x);
return 0;
}
在编译时出现如下错误
ipbox [root] # gcc test.cpp -lstdc++ -o test.o
test.cpp: In function 'int main()':
test.cpp:9: error: expected primary-expression before '{' token
test.cpp:9: error: expected `;' before '{' token
我正在丢失某些东西,但不能动摇我的头。如果我写的是功能,那么效果很好。我很好奇为什么它不能用作宏
答案 0 :(得分:3)
如果您真的想将此实现为宏,则需要从宏内部删除return
。您不能将宏的“结果”分配给变量,因为它不是单个语句。
#include <cstdio>
#define IPV4_ZEROVAL_CHECK(ip, result) {int d1,d2,d3,d4; result = (4 == sscanf(ip, "%d.%d.%d.%d", &d1, &d2, &d3, &d4)) ? ((d1 == 0 && d2 == 0 && d3 == 0 && d4 ==0) ? 0 : 1) : 0;};
int main()
{
char ip[16] = "0.0.1.0";
int x = 99;
IPV4_ZEROVAL_CHECK (ip, x);
printf("Value of x=%d \n",x);
return 0;
}
将其实现为宏没有优势。保留它为函数,如果它足够小,则在发布模式下编译时,编译器将内联它。
答案 1 :(得分:2)
如果展开宏,将会看到问题所在:
int main()
{
char ip[16] = "0.0.1.0";
int x = 99;
x= {int d1,d2,d3,d4; return (4 == sscanf(ip, "%d.%d.%d.%d", &d1, &d2, &d3, &d4)) ? ((d1 == 0 && d2 == 0 && d3 == 0 && d4 ==0) ? 0 : 1) : 0;};
printf("Value of x=%d \n",x);
return 0;
}
{int d1,...}
不是表达式,编译器期望在x=
和{
之间使用表达式和分号。
如果出于某种原因急需宏,则可以编写一个简单得多的宏:
#define IPV4_ZEROVAL_CHECK(ip) (strcmp(ip, "0.0.0.0") == 0)
但是我会推荐该功能
bool IPV4_ZEROVAL_CHECK(const std::string& ip)
{
return ip == "0.0.0.0";
}
或-最简单的解决方案-定义要与之比较的常量:
const std::string zero_IP = "0.0.0.0";
int main()
{
char ip[16] = "0.0.1.0";
bool isZero = ip == zero_IP;
std::cout << "The value is " << isZero;
}
答案 2 :(得分:1)
在实际的编译过程之前,宏通过文本替换来工作。
示例:
给出以下定义:
#define FOO(bar) {return bar * 2;};
此行的文字替换:
x = FOO (ipaddr);
导致编译器看到以下C代码:
x = {return ipaddr * 2;};
这是不正确的C代码。