GCC 前缀递增运算符在将值传递给函数时行为不当
GCC prefix increment operator misbehaving when passing value to the function
当使用 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
为确保问题得到解决,我更新了代码以查看发送到函数的值;
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;
}
在 Windows 10 系统
上使用 GCC 编译的 Bitcount v2 的输出
调试::位计数()::x=127
位数[127] : 7
调试::位计数()::x=127
位数[128] : 7
很明显,GCC 将 X 的旧值发送给 bitcount() 函数。
为了概括这个问题,我写了下面的程序;
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;
}
在 Windows 10 System
上使用 GCC 编译的输出
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
同样,变量的值递增,但旧值发送给函数。
这是我的 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 : 我刚刚看过 The C Programming Language 一书 Kernighan & Ritchie, 第 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));
在 C++ 中未指定函数调用参数的求值顺序,因此行:
printf("bitcount[%d] : %d\n", ++x, bitcount(x));
无法保证 ++x
会在 bitcount(x)
之前计算,因此 bitcount
可能会通过 x
预递增。您所有的编译器都有不同但有效(即符合标准)的行为。
不要在表达式中使用递增:
printf("bitcount[%d] : %d\n", x, bitcount(x));
x++;
printf("bitcount[%d] : %d\n", x, bitcount(x));
当使用 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
为确保问题得到解决,我更新了代码以查看发送到函数的值;
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;
}
在 Windows 10 系统
上使用 GCC 编译的 Bitcount v2 的输出调试::位计数()::x=127 位数[127] : 7
调试::位计数()::x=127 位数[128] : 7
很明显,GCC 将 X 的旧值发送给 bitcount() 函数。
为了概括这个问题,我写了下面的程序;
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;
}
在 Windows 10 System
上使用 GCC 编译的输出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
同样,变量的值递增,但旧值发送给函数。
这是我的 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 : 我刚刚看过 The C Programming Language 一书 Kernighan & Ritchie, 第 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));
在 C++ 中未指定函数调用参数的求值顺序,因此行:
printf("bitcount[%d] : %d\n", ++x, bitcount(x));
无法保证 ++x
会在 bitcount(x)
之前计算,因此 bitcount
可能会通过 x
预递增。您所有的编译器都有不同但有效(即符合标准)的行为。
不要在表达式中使用递增:
printf("bitcount[%d] : %d\n", x, bitcount(x));
x++;
printf("bitcount[%d] : %d\n", x, bitcount(x));