如何让编译器处理这个函数?

时间:2018-02-20 15:13:22

标签: c compilation

我在我的所有代码中都使用了一个函数,它将字符串文字(如"0;1;6")转换为double值(在本例中为0.125)。函数double doztof(const char *string)通过调用其他几个函数和sscanf()来完成此操作。我天真地期望编译器运行该函数并用常量结果替换调用,我的意思是doztof("0;2;3")将始终产生0.1875的常量值,但是我使用的编译器都没有这样做,并且当在循环中使用时我最终每次都运行sscanf()来反复处理相同的常量字符串文字。

为什么编译器不会优化它?作为const传递的字符串文字不能清楚地表明它永远不会改变并且优化出来是安全的吗?我还缺少什么?这是完整的相关代码:

char *skip_string(const char *string, const char *skipstring)       // skipstring must be terminated by a %n
{
    int n=0;
    sscanf(string, skipstring, &n);
    return &string[n];
}

char *skip_whitespace(const char *string)
{
    return skip_string(string, " %n");
}

char *string_parse_fractional_12(const char *string, double *v)
{
    int i, n=0, ret=1, count=0, neg=0;
    double divisor=1., digit;
    char *p = string;

    *v = 0.;

    p = skip_whitespace(p);

    if (p[0] == '-')
    {
        neg = 1;
        p++;
    }

    for (i=0; i<20 && ret==1; i++)
    {
        n=0;
        ret = sscanf(p, "%lf%n", &digit, &n);
        p = &p[n];
        if (ret==1)
        {
            count++;
            *v += digit / divisor;
            divisor *= 12.;
        }

        n=0;
        sscanf(p, ";%n", &n);
        p = &p[n];

        if (p[0]==' ' || p[0]=='\t')    // detect whitespace so that the next sscanf avoids reading the numbers after the whitespace
            ret = 0;
    }

    if (count==0)
        return string;

    if (neg)
        *v = -*v;

    return p;
}

double doztof(const char *string)
{
    double v;
    string_parse_fractional_12(string, &v);
    return v;
}

1 个答案:

答案 0 :(得分:1)

&#34;持续折叠&#34;或者&#34;不断传播&#34;如果它存在,那将是描述这种优化的术语。但它适用于更简单的事情,比如

int x = 6 / 2;
int y = strlen("foo");

与任何合理的恒定折叠期望相比,您的功能非常复杂。如果编译器对即使是sscanf的单个调用进行编译时评估,我也会留下深刻的印象。