4

用于以下 C/C++ 代码

void fun(int* x)
{
    //SOMECODE;//WITHOUT SAVING PREVIOUS VALUE
    if(SOME CONDITION)
    printf("VALUE OF X IS DIFFERENT THAN PREVIOUS CALL \n");
}

int main()
{
    int a;
    a=9;
    fun(&a);
    a=12;
    fun(&a);
    return 0;
}

是否有任何函数或标志值可以为我们提供有关变量是否更改的信息,如果有任何解决方案,请回复

4

4 回答 4

5

如果不提供一些额外的代码来在“最后一次”调用函数期间存储参数,根本没有机会检测是否使用相同的值或其他值调用它。

由于 x 的“当前”值将仅存在于堆栈中,因此一旦您的函数调用完成,它将完全丢失。

在前多线程时代,只需在函数的最后一次运行期间使用静态变量来缓存 x 的值func就可以(几乎)解决了您的问题:

void fun (int x) {
    static int old_value = VALUE_INVALID;

    if(x != old_value)
       printf("VALUE OF X IS DIFFERENT THAN PREVIOUS CALL \n");

    old_value = x;
}

仍然使用这种方法的唯一问题是重入 - 这意味着如果func在信号处理程序中调用缓存值可能会被搞砸。

如果在多线程应用程序中运行,您还必须在使用这种方法时提供某种锁定机制,否则您迟早会搞砸的。

无论如何,您可能会在这种情况下搞砸,因为您必须澄清“最后”调用函数和“执行期间”值的确切含义。

是线程 A 在线程 B 之前进入 func 但仍在执行的当前正确值,还是线程 B 在 B 之后进入但已经完成 func 执行的线程 B 的当前正确值?

于 2013-03-18T17:27:57.147 回答
2

再次阅读您的问题,您不是在检查变量是否更改,而是在检查同一词法标识符的两个不同实例是否不同。

除非通过明确的比较,否则这是不可能的。


关于检测变量更改的原始答案:

在可移植的标准 C 或 C++ 中没有办法。

但是,有一些特定于环境的方法可以检测变量何时更改。您可以使用 MMU 访问控制标志(通过mprotectVirtualProtect)在第一次写入时生成异常,并从处理程序内部设置脏标志。(几乎每个现代操作系统都使用内存映射文件来执行此操作,以确定是否需要将其写回磁盘)。或者您可以使用硬件断点来匹配对该地址的写入(调试器使用它在变量上实现断点)。

与旧值相比,这些都不会像旧值那样有效。(但与旧值相比会错过 ABA 场景)

于 2013-03-18T17:04:38.883 回答
1

无法检查当前值是否与上次调用时发送的值不同。

在运行时,每次调用fun()都会创建一个独立的堆栈帧,其中包含自己的x. fun()无法在此堆栈帧(用于存储局部变量)内保存任何值以供以后调用。

也无法确定“变量是否在不与先前值比较的情况下更改了其值”。

于 2013-03-18T17:07:02.147 回答
0

检查变量是否改变的目的是什么?

如何使用包含变量和标志的结构。更改变量时设置标志并将 struct 传递给 function 。现在测试函数中的标志以检查变量是否已更改。

于 2013-03-18T18:08:33.903 回答