1

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]);
  }
}
}
5
  • 3
    Can you please try to create a Minimal, Complete, and Verifiable Example and show us? And also include the complete error output? Commented Apr 8, 2016 at 7:03
  • try add -std=c99 option. Commented Apr 8, 2016 at 7:04
  • 1
    Is your compiler working in compliance with c99 c standard? Because variable lenght arrays (VLAs) were only added in c99 Commented Apr 8, 2016 at 7:05
  • Show your code instead of describing it. Commented Apr 8, 2016 at 7:07
  • 1
    "#define MAX_LEN = some number" most likely won't compile. You want to remove the =. Commented Apr 8, 2016 at 7:07

3 Answers 3

5

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.

Sign up to request clarification or add additional context in comments.

Comments

1

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.

Comments

0

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.

1 Comment

The reason why the example doesn't compile is because you cannot provide an initializer list to a VLA. Overall, this answer is incorrect. In the year 1999 there was a new C standard.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.