花括号的功能
的说法,我在一些源代码发现行:花括号的功能
if(pthread_create((pthread_t[]){}, 0, start_thread, pthread_args)) {
...
它工作正常,但如何理解第一个参数? 看来,大括号转换为pthread_t[]
类型。
P.s.我GOOGLE了,但没有找到答案,只有一些猜测(某种形式的初始化,或c的遗留功能)
这是compound literal,具有约束冲突,因为initializer braces cannot be empty:
(pthread_t[]){}
使用gcc -std=c99 -Wall -Wextra -Wpedantic
这将产生警告:
compound_literal_pthread.c:6:36: warning: ISO C forbids empty initializer braces [-Wpedantic]
pthread_t *ptr = (pthread_t []){};
结果似乎是一个指针pthread_t
,虽然我不看不到gcc手册中记录的这种行为。请注意,在C++中允许使用空括号作为初始值设定项,它们相当于{ 0 }
。这种行为似乎被C支持,但未被gcc支持。我怀疑这就是发生在这里,让上面的表达式等价于:
(pthread_t[]){ 0 }
在我的系统,pthread_t
是unsigned long
一个typedef
,所以这个表达式将创建pthread_t
仅包含0
元素的数组。该数组将在函数调用中衰减到指向pthread_t
的指针。
作为一个变形的副作用,线程不可连接,因为代码不能以可访问的方式保存'pthread_t'。实际上,线程是分离的,没有正式分离的好处。作为创建线程的一种方式,它留下了许多不足之处。 –
@ JonathanLeffler--很好的音符。 –
我认为* C中的每个类型都可以用'{0}'正确初始化,但我不清楚为什么不允许使用空括号:假设允许初始化对象的任何单个元素为隐式,为什么不一次为他们做到这一点? (对于很多类型,{0}'在技术上可能是允许的,但在清晰的读取意义上不是“正确的”) – Leushenko
您正在创建一个数组与pthread[]
。如果为参数定义长度,则可以在花括号中传递值。
你正在处理的是一个数组初始值设定项,它恰好是空数组。通常你会发现它是:
int my_array[] = (int[]){10, 20, 30};
而且,它还将初始化my_array
包含三个要素。这里没有元素,因此语法尴尬。
是一个空的大括号包含的列表被认为是一个有效的语法? AFAIR,它必须包含至少一个元素。 –
是的,这是一个有效的语法。在这种情况下,你不需要写大括号,但你可以。 –
@ JohannesMols--它不是有效的语法,对初始值设定项使用空括号是违反约束的。 –
这是一个compound literal正如@ some-programmer-dude所提到的。
在这个特定的情况下,它是用来创建一个数组来存储thread_id并稍后释放它,而不需要创建额外的变量。这是必要的,因为pthread_create
不接受NULL作为thread_id
的参数。
这是一个[*复合文字*](http://en.cppreference.com/w/c/language/compound_literal)。 –
@Someprogrammerdude谢谢!就是这样,我想。 – ltWolfik