Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Variable declaration after function's argument list [duplicate]

I stumpled upon a C code, where variables seem to be declared after the argument list of a function. I did not know that this was possible.

In the code, int r and int *a are declared right after the argument list of arr2int. How does this affect the local variables a and r of arr2int?

The actual reason why I want to understand the code is because if I let it run on my linux x86 a[1] = 1 at //MARKER when arr2int ist called the fist time.

But if I let it run ona an ARM-based omap4 dev board a[1]=0 and I dont know why there is a difference.

Could someone comment on this please?

long arr2int(a,r)
int r;
int *a;
{
   int i;
   long mul, result = 0, temp;

   //MARKER
   for (i=1; i<=r; i++) {
      mul = 1;
      temp = a[i]-1;
      while (temp--)
         mul = mul << 1;
      result += mul;
   }
   return(result);
}

And the calling method:

void generateEncodingTable(){
    register int i,j;
    long temp;
    int seed = 133757;

    printf("\n[I] - Generating Encoding Table\n");
    for (pattern = 0; pattern < 4096; pattern++) {
        temp = pattern << 11;          /* multiply information by X^{11} */
        encoding_table[pattern] = temp + get_syndrome(temp);/* add redundancy */
    }

    decoding_table[0] = 0;
    decoding_table[1] = 1;
    temp = 1; 
    for (i=2; i<= 23; i++) {
        temp *= 2;
        decoding_table[get_syndrome(temp)] = temp;
    }

    a[1] = 1; a[2] = 2;

    temp = arr2int(a,2);
    decoding_table[get_syndrome(temp)] = temp;
    for (i=1; i<253; i++) {
        nextcomb(23,2,a);
        temp = arr2int(a,2);
    decoding_table[get_syndrome(temp)] = temp;
    }

    a[1] = 1; a[2] = 2; a[3] = 3;
    temp = arr2int(a,3);
    decoding_table[get_syndrome(temp)] = temp;
    for (i=1; i<1771; i++) {
        nextcomb(23,3,a);
        temp = arr2int(a,3);
        decoding_table[get_syndrome(temp)] = temp;
    }
}
like image 336
Richard Laurant Avatar asked Aug 01 '13 12:08

Richard Laurant


1 Answers

As mention by others, this is an early style of function coding.

Following is a pitfall of that style. Be aware there is no type checking on passed parameters. It may explain your run time differences.

Say you declare a function

int foo(a,b,c);

All the compiler sees at that point is a function named "foo" taking 3 arguments and returning an int. Thus usage checking is limited to that.

Let's assume sizeof(short) < sizeof(int) < sizeof(long) and the function is defined as

int foo(a,b,c)
  int a;
  long b;
  int c;
{ /* code body */ }

Notice the following usage of foo

int d,e,f;
d = foo(1,2L,3);
e = foo((short)1,2L,3);
f = foo(1,2,3);

The first usages works fine, the right size integers are passed to foo.
The 2nd usages also works fine. The first argument is promoted to int size before the call, much like printf("%d", (short)2) promotes (short)2 to int before passing to printf().
The 3rd is a problem as the compiler does not know the second argument needs to be long. Thus the data passed to foo is not passed correctly. --> UB

like image 92
chux - Reinstate Monica Avatar answered Oct 05 '22 19:10

chux - Reinstate Monica