在C ++中使用宏验证IP时出错

时间:2018-08-23 13:29:35

标签: c++ macros

我需要使用宏检查我的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

我正在丢失某些东西,但不能动摇我的头。如果我写的是功能,那么效果很好。我很好奇为什么它不能用作宏

3 个答案:

答案 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代码。

  • 您的C课本应该涵盖此内容
  • 在大多数情况下,
  • 最好使用函数而不是宏。