【问题标题】:unfamiliar c language expression, related to pthreads不熟悉的c语言表达,与pthreads有关
【发布时间】:2020-04-06 06:12:36
【问题描述】:

这是一段代码。有人可以解释最后三个布尔语句。我以前从未见过这种语法。我不知道那里发生了什么。它是其他东西的简写吗?

我在三个 bool 语句上方包含了代码以提供一些上下文。

void *bob;
void *tod;
void *jon;

pthread_t *thrdA= malloc(9 * sizeof(pthread_t));
pthread_t *thrdB= malloc(9 * sizeof(pthread_t));
pthread_t *thrdC = malloc(9 * sizeof(pthread_t));

for(int i = 0; i<9; i++) {
    pthread_create(&thrdA[i], NULL, FUNCT1, (void*)SAS);
}

for(int i = 0; i<9; i++) {
    pthread_create(&thrdB[i], NULL, FUNCT2, (void*)SAS);
}

int x= 0;
for (int i = 0; i < 5; i++) {
    for (int j = 0; j < 5; j++) {
        pthread_create(&thrdC[x], NULL, FUNCT3, (void*)SAS);
        x++;
    }
}
for(int i=0; i<9; i++) {
   pthread_join(thrdA[i], &bob);
   pthread_join(thrdB[i], &tod);
   pthread_join(thrdC[i], &jon);
}    


bool x = (unsigned long)bob== 0;
bool z = (unsigned long)tod== 0;
bool y = (unsigned long)jon== 0;

【问题讨论】:

  • @AlexF 没错,但应该讨论一下 bob 的数据类型的含义。
  • 这主要是因为pthreads返回一个void *,所以很多需要数字返回线程的人将它们用作转换值而不是指向值的指针。

标签: c syntax boolean pthreads


【解决方案1】:

我们必须查看线程回调才能确定,但​​这闻起来像是通过与void* 进行转换来按值传递整数的可疑代码。

由于 pthread 回调采用 void* 并返回 void*,显然有很多奇怪的想法,这些 void 指针也可以用于按值传递整数。也就是说,将整数转换为/从void* 转换,而不是让指针指向已分配的对象。

当我们还处于 32 位 PC 时代时,这种脆弱的 hack 可能是幸运的。如今,当 x86_64 指针通常是 64 位但 int 仍然是 32 位时,情况就不那么好了。

如果有问题的代码使用了这样的 hack,那么这就解释了对unsigned long 的奇怪且看似毫无意义的强制转换。

不要使用这种蹩脚的技巧,句号。


关于表达式本身:bob == 0,这是简单的布尔运算。将相等/关系运算符的结果分配给bool 变量是非常好的。实际上,这些运算符的返回类型在 C 中是 int(与 C++ 不同),但无论如何,该返回类型都可以安全地视为类型 bool

请记住,您必须包含 stdbool.h 才能使用 bool - 在 C 中,这只是实际布尔关键字 _Bool 的宏。

【讨论】:

  • “Crappy hacks”是对您所描述的实践的不恰当描述。虽然一般来说,将整数(不是值为 0 的整数常量)转换为 void * 并返回确实具有实现定义的语义,并且会产生陷阱表示或未定义的行为,但问题是关于 pthreads,它由 POSIX 定义对于 POSIX 环境,可以依靠将不宽于 intptr_t 的整数转换为指针类型并返回到相同的整数类型来重现原始整数值。
  • @JohnBollinger 尽管如此,由于这种 hack 导致的错误的可能性很大。例如,假设 main 中没有强制转换回整数类型。然后,您突然将 void 指针与空指针表示进行比较,空指针表示可以是任何东西。 Endianess 也会导致有趣的错误场景。底线是创建线程是一种昂贵的操作,与线程创建开销相比,将指针传递给对象与将值强制转换为指针是一种未成熟的优化。
  • 这个^ 对话超出了我的理解。我是本科生,不是专家
【解决方案2】:

double 等于 == 是一个布尔运算符,例如 if (x==0)

  • 如果 x 为零,则该语句的计算结果为 true
  • 否则该语句将评估为假

换句话说,就像你说的那样

if trueif false

一些 C 编译器会识别 bool 语句,因为它只是一个宏 (https://pubs.opengroup.org/onlinepubs/009695399/basedefs/stdbool.h.html)。

本质上,就像 Alex F 所说: x、y 和 z 是 bool 类型(它们将被识别为 true 或 false),基于它们前面正在评估的布尔表达式的返回。引用 Alex F 的话: 如果 bob == 0,x = true,否则 x = false

(unsigned long) 是一种种姓

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-07-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-14
    相关资源
    最近更新 更多