I am not able to understand why the compiler doesn't warn when assigning incompatible pointers through (?:) but does warn on direct assignment.
Compiler warns in this case:
test.c: In function ‘main’: test.c:8:4: warning: assignment to ‘uint32_t *’ {aka ‘unsigned int *’} from incompatible pointer type ‘uint32_t **’ {aka ‘unsigned int **’} [-Wincompatible-pointer-types] 8 | a = array; | ^
#include <stdint.h>
#include <stdlib.h>
int main(void)
{
uint32_t *array[10], *a;
a = array;
}
No warning in the following case:
#include <stdint.h>
#include <stdlib.h>
int main(void)
{
int b = 8;
uint32_t *array[10], *a;
a = (b >= 8) ? array : malloc(8);
}
Environment:
Gcc version 9.3.0
Ubuntu 20.04
compilation cmd: gcc test.c -o test.out
CodePudding user response:
The type of the expression (b >= 8) ? array : malloc(8) is void* (because malloc(8) has the type void*). You can see this by doing something non-sensical and having the compiler tell you:
((b >= 8) ? array : malloc(8)) * 5;
<source>:10:36: error: invalid operands to binary * (have 'void *' and 'int')
10 | ((b >= 8) ? array : malloc(8)) * 5;
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ^
| |
| void *
void* can be implicitly converted to a pointer of any type, which is why the compiler doesn't complain when you assign that value to a.
CodePudding user response:
From the C Standard (6.5.15 Conditional operator)
- ... otherwise, one operand is a pointer to void or a qualified version of void, in which case the result type is a pointer to an appropriately qualified version of void.
The function malloc returns a pointer of the type void *. So the type of the expression with the conditional operator is void *. And a pointer of the type void * can be assigned to a pointer of any other object type.
From the C Standard (6.3.2.3 Pointers)
1 A pointer to void may be converted to or from a pointer to any object type. A pointer to any object type may be converted to a pointer to void and back again; the result shall compare equal to the original pointer.
In fact you have
a = ( void * )(b >= 8 ? array : malloc(8) );
