c++ - GCC 前缀递增运算符在将值传递给函数时行为不当

标签 c++ c gcc mingw prefix-operator

<分区>

当使用 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 & RitchieThe 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));

最佳答案

在 C++ 中未指定函数调用参数的求值顺序,因此行:

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

不能保证 ++x 会在 bitcount(x) 之前计算,所以 bitcount 可能会被传递给 x 预递增。您所有的编译器都有不同但有效(即符合标准)的行为。

关于c++ - GCC 前缀递增运算符在将值传递给函数时行为不当,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36766590/

相关文章:

c++ - 如何使用SetWindowLong来寻址类成员函数?

c++ - abi::__cxa_demangle 无法重用其自身返回的内存

c - 传递 const 变量时不兼容的指针类型

c++ - 为什么隐式转换在 g++ 中不起作用

c++ - 如何使用 C++ 在 Windows 上创建具有 UNICODE 路径的文件

c++ - 在 C++ 头文件/实现文件中放置#undef 指令的正确方法

c++ - 我可以使用 Webassembly 从磁盘读取文件吗?

c++ - 链接到 C++ 库时在 C 中使用 setjmp 和 longjmp

c - 最大堆段错误

C - 对函数参数使用与函数本身相同的名称是不好的做法吗?