1

I have a little C program which takes a number of vectors and their corresponding coefficients. With this information, it calculates the length (modulus) of the vector. Next, the program sorts the array with vectors by its length and then displays all vectors in the right order.

Everything seems to work fine. However, when I compile the code with the -wall and -ansi arguments I receive the following warnings:

|23|warning: ISO C90 forbids variable-size array 'v'
|23|warning: ISO C90 forbids mixed declarations and code
|44|warning: passing argument 1 of 'swap' from incompatible pointer type
|44|warning: passing argument 2 of 'swap' from incompatible pointer type

The code I use:

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

void swap(double **p, double **q)
{
    double *tmp;

    tmp = *p;
    *p = *q;
    *q = tmp;
}

int main()
{
    int dim, num;
    int i, j;
    double **w;

    scanf("%d %d", &dim, &num);
    w = calloc(num, sizeof(double *));

    double v[num];

    /* Get vector coefficients for each vector and calculate the length of each vector */
    for(i = 0; i < num; i++)
    {
        w[i] = calloc(dim, sizeof(double));

        for(j = 0; j < dim; j++)
        {
            scanf("%le", &w[i][j]);
            v[i] += pow(w[i][j], 2);
        }
    }

    /* Sort vectors by length */
    for(i = 0; i < num-1; ++i)
    {
        for(j = num-1; j > i; --j)
            if(v[j-1] > v[j])
            {
                swap(&w[j-1], &w[j]);
                swap(&v[j-1], &v[j]);
            }
    }    

    /* Display vectors, including their coefficients, ordered by length */
    for(i = 0; i < num; i++)
    {
        for(j = 0; j < dim; j++)
        {
            printf("%e", w[i][j]);
            if(j != dim)
                printf(" ");
        }
        printf("\n");
    }

    return 0;
}

Any ideas on how to fix those warnings?

Thanks in advance.

Laurens
  • 63
  • 1
  • 13

2 Answers2

1

Try:

double *v;
v=(double *)malloc(num * sizeof(double));

instead of

double v[num];
Florin Petriuc
  • 1,146
  • 9
  • 16
  • If the intention is to be c compatible, and not c99, you also need to lift the declaration of v to the top of the function. – JasonD Nov 24 '12 at 14:46
  • 1
    @JasonD C allows mixed declarations and code, that hasn't changed since C99. – Daniel Fischer Nov 24 '12 at 14:48
  • I still received the mixed declarations warning, however I fixed it by putting `double *v;` at the declarations block of my main function. – Laurens Nov 24 '12 at 14:50
  • c++ allows mixing declarations and code, c does not, until c99. – JasonD Nov 24 '12 at 14:52
  • 1
    @JasonD And that's already 13 years old. The current version of C is the language specified in the C2011 standard from last year. C sans qualifiers ought to refer to that, since that standard overrides C99, which in turn overrode the C89/C90 standard. If you mean C89, say C89. – Daniel Fischer Nov 24 '12 at 14:55
  • Don't cast the return in C: http://stackoverflow.com/questions/605845/do-i-cast-the-result-of-malloc – Jens Gustedt Nov 24 '12 at 15:09
  • @DanielFischer Only 13 years? :) Anyway, had I just said 'c' in isolation I appreciate that it might be ambiguous or inaccurate. However I wrote "not c99" and "until c99", which is a clear differentiation. So I think I did write what I meant... – JasonD Nov 24 '12 at 15:11
  • @JasonD You wrote "If the intention is to be c compatible", and C is now C2011 and allows mixed declarations and code. I'm just insisting that people be explicit when they talk about an obsolete version of a language and don't usurp the unqualified name of the language. – Daniel Fischer Nov 24 '12 at 15:16
1

You are trying to swap two different types with the same function,

swap(&w[j-1], &w[j]);
swap(&v[j-1], &v[j]);

where &w[j] is a double** and &v[i] a double*. That doesn't work, since C doesn't have overloading. You can't even use a void* argument, since you need to store the pointed-to values in between.

You need two separate functions for that, or a macro (but that loses type safety).

As for mixing declarations and code and the variable length array, use -std=c99 instead of -ansi.

Daniel Fischer
  • 181,706
  • 17
  • 308
  • 431
  • Thanks, creating two separate swap-functions in combination with the solution of Petriuc did the trick. The reason why I use -ansi is because my code needs to satisfy this requirement due to regulations of this assignment (it is for a university course). – Laurens Nov 24 '12 at 14:46
  • Regardless of whether you `malloc` or use a variable length array, I still recommend not using `-ansi`. C99 and C2011 introduced many very useful features, allowing mixed declarations and code is not the least of them. Oh, I just saw your edit. If it's an external requirement, then of course you have to. – Daniel Fischer Nov 24 '12 at 14:51