R.k*_*ana 0 c gcc conditional-operator void-pointers implicit-conversion
我无法理解为什么编译器在分配不兼容的指针时不发出警告(?:),但在直接分配时发出警告。
在这种情况下编译器会发出警告:
\n\n\ntest.c:在函数 \xe2\x80\x98main\xe2\x80\x99 中:test.c:8:4:警告:分配给\n\xe2\x80\x98uint32_t *\xe2\x80\x99 {aka \xe2 \x80\x98unsigned int *\xe2\x80\x99} 来自不兼容的指针类型\n\xe2\x80\x98uint32_t **\xe2\x80\x99 {aka \xe2\x80\x98unsigned int **\xe2\x80\x99 } [-Win兼容指针类型]\n8 | a = 数组;\n| ^
\n
#include <stdint.h>\n#include <stdlib.h>\n\nint main(void)\n{\n uint32_t *array[10], *a;\n a = array;\n}\nRun Code Online (Sandbox Code Playgroud)\n以下情况不会发出警告:
\n#include <stdint.h>\n#include <stdlib.h>\n\nint main(void)\n{\n int b = 8;\n uint32_t *array[10], *a;\n\n a = (b >= 8) ? array : malloc(8);\n}\nRun Code Online (Sandbox Code Playgroud)\n环境:
\nGcc version 9.3.0\nUbuntu 20.04\ncompilation cmd: gcc test.c -o test.out\nRun Code Online (Sandbox Code Playgroud)\n
表达式的类型(b >= 8) ? array : malloc(8)是void*(因为malloc(8)具有类型void*)。您可以通过做一些无意义的事情并让编译器告诉您来看到这一点:
((b >= 8) ? array : malloc(8)) * 5;
Run Code Online (Sandbox Code Playgroud)
<source>:10:36: error: invalid operands to binary * (have 'void *' and 'int')
10 | ((b >= 8) ? array : malloc(8)) * 5;
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ^
| |
| void *
Run Code Online (Sandbox Code Playgroud)
void*可以隐式转换为任何类型的指针,这就是为什么当您将该值分配给 时编译器不会抱怨a。
来自 C 标准(6.5.15 条件运算符)
- ...否则,一个操作数是指向 void 或 void 的限定版本的指针,在这种情况下,结果类型是指向 void 的适当限定版本的指针。
该函数malloc返回类型为 的指针void *。所以带有条件运算符的表达式的类型是void *。并且该类型的指针void *可以分配给任何其他对象类型的指针。
来自 C 标准(6.3.2.3 指针)
1 指向 void 的指针可以与指向任何对象类型的指针相互转换。指向任何对象类型的指针都可以转换为指向 void 的指针,然后再转换回来;结果应等于原始指针。
事实上你有
a = ( void * )(b >= 8 ? array : malloc(8) );
Run Code Online (Sandbox Code Playgroud)