如果 func() 修改全局变量,int sum = func(1) + func(2) 是否会导致未定义的行为

问题描述 投票:0回答:1

受这篇SO post的启发,我想知道以下代码片段是否会导致UB,因为

add_func()
mul_func()
都可以同时以未指定的顺序修改
counter

int counter = 0;

int mul_func(int x) {
  counter *= x;
  x = counter;
  return x;
}

int add_func(int x) {
  counter += x;
  x = counter;
  return x;
}

int main(void) {
  int sum = add_func(3) + mul_func(2);
}

如果是这样,如果我向它们添加互斥体有帮助吗?:

int counter = 0;

pthread_mutex_d mtx;

int mul_func(int x) {
  pthread_mutex_lock(&mtx);
  counter *= x;
  x = counter;
  pthread_mutex_unlock(&mtx);
  return x;
}

int add_func(int x) {
  pthread_mutex_lock(&mtx);
  counter += x;
  x = counter;
  pthread_mutex_unlock(&mtx);
  return x;
}

int main(void) {
  pthread_mutex_init(&mtx);
  int sum = add_func(3) + mul_func(2);
  pthread_mutex_destroy(&mtx);
}

虽然结果可能是不确定的(如许多多线程程序的情况),但即使没有数据竞争,“无序”性质是否仍然会导致 UB?

c undefined-behavior
1个回答
1
投票

确实由编译器决定调用函数的顺序。它会在添加之前调用两者,但这就是你所知道的。

你的互斥锁不做任何事情;这些用于同步线程,而不是强制您的编译按照您想要的顺序评估事物。您的代码不会并行执行操作,它只是以未指定的顺序执行操作。

强制执行排序的正确方法是这样的

const int left=add_func(3);
const int right=mul_func(2);
int sum=left+right;

这样,编译器别无选择,只能按照您提供的顺序调用函数。

© www.soinside.com 2019 - 2024. All rights reserved.