1

Prefix Increment operator not sending incremented value of the variable (x) in a call to printf(), when compiled with GCC.

Here is my code;

#include <stdio.h>

int bitcount(unsigned);

int main()
{
    unsigned int x = 127;

    printf("bitcount[%d] : %d\n", x, bitcount(x));
    printf("bitcount[%d] : %d\n", ++x, bitcount(x));

    return 0;
}

int bitcount(unsigned int x)
{
    int bitcount = 0;
    for(; x != 0; x >>= 1)
        if( x & 1 )
            bitcount++;

    return bitcount;
}

in main() method, the problem is at the line below;

printf("bitcount[%d] : %d\n", ++x, bitcount(x));

X should be incremented and send to the bitcount() with the incremented value of x. The value of x is incremented however, instead of incremented value, the old value is send to the bitcount() function.

I've tried the same thing with MS VS, this misbehaving didn't occur. The outputs are as below;

Output of Program compiled with GCC on Windows 10

D:\C\chapter2>gcc bitcount.c -o bitcount.exe

D:\C\chapter2>bitcount
bitcount[127] : 7
bitcount[128] : 7

Output of Program compiled with MS VS on Windows 10

bitcount[127] : 7
bitcount[128] : 1

To ensure the problem, I've updated code to see the value which is sent to the function;

Bitcount V2

#include <stdio.h>

int bitcount(unsigned);

int main()
{
    unsigned int x = 127;

    printf("bitcount[%d] : %d\n", x, bitcount(x));
    printf("bitcount[%d] : %d\n", ++x, bitcount(x));

    return 0;
}

int bitcount(unsigned int x)
{
    printf("\nDebug::\tbitcount()::x=%d\n", x);
    int bitcount = 0;
    for(; x != 0; x >>= 1)
        if( x & 1 )
            bitcount++;

    return bitcount;
}

Output of Bitcount v2 compiled with GCC on Windows 10 system

Debug:: bitcount()::x=127 bitcount[127] : 7

Debug:: bitcount()::x=127 bitcount[128] : 7

As it is obvious, GCC sending the old value of X to bitcount() function.

To generalize the problem, I've written the program below;

InsideFunc.c

#include <stdio.h>

int func(unsigned);

int main()
{
    unsigned int x = 127;

    printf("x: %d, func(): %d\n",   x, func(x));
    printf("x: %d, func(): %d\n", ++x, func(x));

    return 0;
}

int func(unsigned x)
{
    printf("\n\tDebug::func()::x=%d\n", x);

    return x;
}

Output compiled with GCC on Windows 10 System

D:\C\chapter2>gcc InsideFunc.c -o InsideFunc.exe

D:\C\chapter2>InsideFunc

    Debug::func()::x=127

x: 127, func(): 127

    Debug::func()::x=127

x: 128, func(): 127

Again, value of the variable incremented but old value send to the function.

Here is my gcc version;

D:\C\chapter2>gcc --version
gcc (GCC) 5.2.0
Copyright (C) 2015 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

Any ideas ?

Late Note : I've just seen on The C Programming Language book of Kernighan & Ritchie, page 49 that which explains the order of evaluation in the function arguments are uncertain and compiler dependent;

Similarly, the order in which function arguments are evaluated is not specified, so the statement

printf("%d %d\n", ++n, power(2, n)); /*WRONG */

can produce different results with different compilers, depending on whether n is incremented before power is called. The solution, of course, is to write

++n;

printf("%d %d\n", n, power(2, n));

4

2 回答 2

1

不要在表达式中使用增量:

printf("bitcount[%d] : %d\n", x, bitcount(x));
x++;
printf("bitcount[%d] : %d\n", x, bitcount(x));
于 2016-04-21T10:24:01.910 回答
1

在 C++ 中未指定函数调用参数的评估顺序,因此如下:

printf("bitcount[%d] : %d\n", ++x, bitcount(x));

不能保证++x会在之前进行评估bitcount(x),因此bitcount可能会通过x预增量。您所有的编译器都有不同但有效(即符合标准)的行为。

于 2016-04-21T10:22:06.743 回答