gil
gil

Reputation: 2552

array length variable - c

i'm writing a c program and i've noticed that whenever i declare my array length with const variable(const size_t MAX_LEN = some number) it sends me errors. on the other hand, when i'm using (#define MAX_LEN = some number) as my array length declaration it works just fine.

the exact error i get : LinSeperator.c:45:2: error: variable length array ‘arr’ is used [-Werror=vla] double theAns, arr[MAX_LEN]; ^

could anyone help me figure out why it happens?

EDIT: here's my code: this is my LinSeperatorHelperFunc.h:

#pragma once
#include <stdio.h>

const size_t MAX_LEN = 199;

typedef struct Orange
{
double arr[MAX_LEN];
int tag;
}orange;


void learnProg(orange *o, double w[], int d);

void filePrinter(const char *output, FILE **fileIn, int d, double w[]);

this is my .c file:

#include "LinSeperator.h"
#include "LinSeperatorHelperFunctions.h"
#define NEG_ONE (-1)
#define NegToPos (2)




void LinSeperator(const char *In, const char *Out){
FILE * input;
orange o;
int d , pos, neg ,i , j;
//initializing the hypothesis vector as requested in step 1
double w[MAX_LEN];
for(i = 0 ; i<MAX_LEN ; i++){
    w[i] = 0;
}
input = fopen(In,"r");
if(input == NULL){
    printf("file doesnt exists");
    return;
}
fscanf(input, "%d %d %d", &d , &pos, &neg);

for(i = 0; i<pos+neg ; i++){
    o.tag = i<pos ? 1: -1;

    for(j = 0 ; j<d ; j++){
        fscanf(input, "%lf", &o.arr[j]);
        //removing ',' from being scanned
        if(j!= d-1){
            fgetc(input);
        }
    }
    learnProg(&o,w,d);
}
filePrinter(Out, &input, d, w);
fclose(input);

 }

void filePrinter(const char* out, FILE **in, int d, double w[]){
int i;
double theAns, arr[MAX_LEN];
FILE *output = fopen(out, "w");
if (output == NULL){
    printf("couldnt write to the current file");
    return;
}
while(!feof(*in)){

    for (i=0; i<d; i++) {
        fscanf((*in), "%lf", &arr[i]);
        if(feof(*in))//if we finished the checked vectors we should finish the file and the function 
        {
            fclose(output);
            return;
        }
        //preventing from reading the "," between each col
        if(i!=d-1){
            fgetc(*in);
        }
    }
    theAns=0;
    for (i=0; i<d; i++){
        theAns+=arr[i]*w[i];
    }
        //if ans >=0 print 1 to file else -1
    fprintf(output, "%d\n", NEG_ONE+NegToPos*(theAns>=0)); 
}
fclose(output);
  }




 //the learning progress algo
  void learnProg(orange *o, double w[], int d){
int i, negOrPos = (*o).tag;
double theAns = 0;
for(i = 0; i<d ; i++){
    theAns += ((*o).arr[i] * w[i]); //2.1
}
//has the same sign
if( (negOrPos * theAns) > 0 ){  //2.2
    return ;
}
else{
  for(i = 0; i<d ; i++){
      w[i] += (negOrPos * (*o).arr[i]);
  }
}
}

Upvotes: 1

Views: 2844

Answers (3)

Arjun Sreedharan
Arjun Sreedharan

Reputation: 11453

In C, const do not create a compile-time constant. It merely creates a read only variable. The distinction is important.

When you use:

#define MAX_LEN 701

It's a directive given to the preprocessor to replace all occurrences of MAX_LEN with 701. When the compiler gets your code, all it gets to see is the numerical constant.

C 90 standard allows to declare arrays with with numerical constant length only. However, if you were to use C 99 you could use variable length arrays.

With gcc, you can use --std=c99 or --std=c90 to set what standard to compile your code against.

Upvotes: 5

vgonisanz
vgonisanz

Reputation: 11930

It's simply a limitation of the language. You cannot use a const size_t in a array declaration. In example:

const size_t dimensions = 3;
size_t reality[dimensions]={3,8,12};

It won't compile, but

#define dimensions 3
size_t reality[dimensions]={3,8,12};

Works.

The sizes of statically-bounded arrays need to be constant expressions, and unfortunately in C that's only something like a literal constant or a sizeof expression or such like, but not a const-typed variable. You can try using dynamic allocation of array of pointers, but its more complicated to use.

As Lundin say, technically the standard C99 say that you cannot provide an initializer list to a VLA. Reference here.

Upvotes: 0

Lundin
Lundin

Reputation: 213513

It depends on where the array is declared.

If it is declared at file scope (outside any function) then the array size must be a constant expression, like a #define raw number. Unfortunately C does not regard const variables as constant expressions.

If the array is declared at local scope, the problem is just that you are using a far too old compiler, or alternatively that you have misconfigured GCC. In case of GCC, tell it to compile your code according to the C standard language: gcc -std=c11 -pedantic-errors -Wall -Wextra.

Upvotes: 1

Related Questions