<分区>
当使用 GCC 编译时,前缀增量运算符不会在调用 printf()
时发送变量 (x) 的增量值。
这是我的代码;
#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;
}
在main()方法中,问题出在下面一行;
printf("bitcount[%d] : %d\n", ++x, bitcount(x));
X 应该增加并发送到 bitcount()
增加的 x 值。然而,x 的值递增,而不是递增的值,旧值被发送到 bitcount()
函数。
我已经用 MS VS 尝试过同样的事情,但没有发生这种不当行为。输出如下;
在 Windows 10 上使用 GCC 编译程序的输出
D:\C\chapter2>gcc bitcount.c -o bitcount.exe
D:\C\chapter2>bitcount
bitcount[127] : 7
bitcount[128] : 7
在 Windows 10 上使用 MS VS 编译程序的输出
bitcount[127] : 7
bitcount[128] : 1
为确保问题解决,我更新了代码以查看发送到函数的值;
比特计数 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;
}
在Windows 10系统上使用GCC编译Bitcount v2的输出
调试::bitcount()::x=127 位数[127] : 7
调试::bitcount()::x=127 位数[128] : 7
很明显,GCC 将 X 的旧值发送给 bitcount() 函数。
为了概括这个问题,我写了下面的程序;
内部函数.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;
}
在Windows 10系统上使用GCC编译输出
D:\C\chapter2>gcc InsideFunc.c -o InsideFunc.exe
D:\C\chapter2>InsideFunc
Debug::func()::x=127
x: 127, 函数(): 127
Debug::func()::x=127
x: 128, 函数(): 127
同样,变量的值递增,但旧值发送给函数。
这是我的 gcc 版本;
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.
有什么想法吗?
Late Note :我刚刚在 Kernighan & Ritchie 的 The C Programming Language 一书中看到,第 49 页解释了顺序函数参数中的评估是不确定的并且依赖于编译器;
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));