Reputation: 475
I am new to C and I am trying to write a function called "print_array" that prints out any arrays of type int, float and double. I am trying to do this by function overloading (I read about this in a book). So I came up with the following code:
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <math.h>
#define len(x) (sizeof(x) / sizeof((x)[0]))
#define print_array(array, length_array)_Generic((array), double: print_double, float: print_float, default: print_int)(array, length_array)
void print_int(int *array, size_t length_array) {
printf("{");
for (int i = 0; i < length_array-1; i = i+1) {
printf("%d, ", array[i]); }
printf("%d} \n", array[length_array-1]); }
void print_float(float *array, size_t length_array){
printf("{");
for (int i = 0; i < length_array-1; i = i+1) {
printf("%f, ", array[i]); }
printf("%f} \n", array[length_array-1]); }
void print_double(double *array, size_t length_array) {
printf("{");
for (int i = 0; i < length_array-1; i = i+1) {
printf("%f, ", array[i]); }
printf("%f} \n", array[length_array-1]); }
int main()
{
int A[3] = {1,2,3};
double B[4] = {1.2, 3, 4.5, 6.8};
float C[4] = {1.2, 3, 4.5, 6.8};
print_int(A, len(A));
print_double(B, len(B));
print_float(C, len(C));
printf("____________________________________________________ \n");
print_array(A, len(A));
print_array(B, len(B));
print_array(C, len(C));
return 0;
}
Please note that I defined a macro called "len" to get the length of arrays quickly. The functions "print_int", "print_float" and "print_double" are straightforward printing functions for the corresponding array type.
I tested these functions in the main function and they do as I expected. But my function "print_array" prints some weird values for the float and double type, but it works for the int type. Here is my output:
{1, 2, 3}
{1.200000, 3.000000, 4.500000, 6.800000}
{1.200000, 3.000000, 4.500000, 6.800000}
____________________________________________________
{1, 2, 3}
{858993459, 1072902963, 0, 1074266112}
{1067030938, 1077936128, 1083179008, 1088002458}
Process returned 0 (0x0) execution time : 0.031 s
Press any key to continue.
Could you please tell me what I am doing wrong?
Upvotes: 1
Views: 310
Reputation: 134048
You're using the default
generic association for every case that compiles... If you'd put int
case separately you'd notice that it is never selected.
The problem is that you're selecting by the array type, instead of the element type. Try
_Generic((*array), ...)
to actually use an array element as the controlling expression.
With this one-character fix the output is
{1, 2, 3}
{1.200000, 3.000000, 4.500000, 6.800000}
{1.200000, 3.000000, 4.500000, 6.800000}
____________________________________________________
{1, 2, 3}
{1.200000, 3.000000, 4.500000, 6.800000}
{1.200000, 3.000000, 4.500000, 6.800000}
Actually you should have gotten many warnings, for example:
warning: passing argument 1 of ‘print_int’ from incompatible pointer type [-Wincompatible-pointer-types]
print_array(B, len(B));
note: in definition of macro ‘print_array’
#define print_array(array, length_array)_Generic((array), double: print_double, float: print_float, default: print_int)(array, length_array)
^~~~~
111111.c:10:6: note: expected ‘int *’ but argument is of type ‘double *’
void print_int(int *array, size_t length_array) {
^~~~~~~~~
Upvotes: 3