-1

I was writing the following code

#include<stdio.h>

void fun(int n) {
    int a[n] = {0};
}

void main() {
    int a[4] = {0};
    int i = 0;
    fun(3);
}

and got this error

test.c: In function 'fun':
test.c:5:5: error: variable-sized object may not be initialized

while if I change the function fun to:-

void fun(int n) {
    int a[n], i = 0;
    for(i = 0; i < n; i++) {
        a[i] = 0;
    }
}

it works fine. I know that the error is occuring because it's not allowed in the compiler's specification but what i want to know is why is it not possible to be implemented? Is it due to some compile time or run time evaluation issue? I have seen the answer of other question but i need a more elaborated answer.

Vaibhav Verma
  • 127
  • 1
  • 11
  • 2
    I guess the implicit question is "why". Your first attempt is an error because the language rules say so. The second attempt is OK and you should use it. If you have some other question, please state it explicitly. – n. m. could be an AI Jul 30 '18 at 05:31
  • 1
    The wide divergence of oddities in the answers provided in this post is a testimonial to (a) what happens when you don't actually ask a *question* so people begin *guessing* what the question was, and (b) how poorly engineers seem to guess. Indeed, most of the answers will have little-if-anything to do with what is *likely* your problem, but clarity in your question shall deliver us from that evil. Kindly revise your post to ask a *specific* question. – WhozCraig Jul 30 '18 at 06:04
  • Where do you want to use that array, once initialized, in main or inside fun? – Bob__ Jul 30 '18 at 06:21
  • Possible duplicate of [C compile error: "Variable-sized object may not be initialized"](https://stackoverflow.com/questions/3082914/c-compile-error-variable-sized-object-may-not-be-initialized) – ggorlen Jul 30 '18 at 07:05

4 Answers4

2

Variable Length Array cannot be initialized like this

int a[n]={0};

From C Standards#6.7.9p3 Initialization [emphasis added]

The type of the entity to be initialized shall be an array of unknown size or a complete object type that is not a variable length array type.

Using loop is one way to initialize the variable length array's. You can also use memset like this:

memset(a, 0, sizeof a);

Additional:

The C99 compiler should support the Variable Length Array's but they were made optional in C11 compiler.

H.S.
  • 11,654
  • 2
  • 15
  • 32
0

An easy way is to send the size of array along with other parameters Remember that you should send size before an array with that size

void fun(int n,int a[n]){

}

Although you have other alternatives like sizeof()

I'mDoneOK
  • 39
  • 2
  • 9
  • Just curious about this--what is your reference on sending size before array of that size? I haven't heard of that before (I usually pass the size after the array). – ggorlen Jul 30 '18 at 06:46
  • "*... other alternatives like `sizeof()`*" to do exactly what? – alk Jul 30 '18 at 09:27
  • the array decays to a pointer so the knowledge about the size is lost in the call. – Kami Kaze Jul 30 '18 at 11:13
  • I see the point of passing the size in, but I'm asking why **before** the array in the param list rather than **after**. I write my headers like `void doit(char *a, int size)` rather than `void doit(int size, char *a)`. – ggorlen Jul 30 '18 at 16:41
  • @ggorlen Aren't you confusing `sizeof` with `strlen`? – Bob__ Jul 30 '18 at 18:46
  • @ggorlen Also, [here](http://www.open-std.org/JTC1/SC22/WG14/www/docs/n2086.htm): *"Additional Principle for C2x ...15. Application Programming Interfaces (APIs) should be self-documenting when possible. In particular, the order of parameters in function declarations should be arranged such that the size of an array appears before the array. The purpose is to allow Variable-Length Array (VLA) notation to be used. This not only makes the code's purpose clearer to human readers, but also makes static analysis easier. Any new APIs added to the Standard should take this into consideration."* – Bob__ Jul 30 '18 at 18:58
  • @Bob__ Yeah, I meant `strlen`. Sorry. Thanks for the reference--that's what I was looking for! I'll update my approach. Coming from higher-level languages, I intuitively preferred to pass "heavy" parameters like arrays before small ones like numbers (for readability, so I thought). – ggorlen Jul 30 '18 at 20:08
  • @alk I meant to say `strlen` may be used to determine the length of the array if passed without accompanying length parameter, but this is a *O(n)* operation. – ggorlen Jul 30 '18 at 20:10
  • I see. Still you do not want to pass an `int*` to a function expecting a `char*`, as `strlen()` does. Also `strlen()` does not work on any `char*` but only on those pointing to a `'\0'`, or to the 1st `char` of an array of `char`s holding at least one `'\0'`, namely a "C-string". – alk Jul 31 '18 at 06:25
0

As an addition to H.S. answer:

From C Standards#6.7.9p3 Initialization [emphasis added]

The type of the entity to be initialized shall be an array of unknown size or a complete object type that is not a variable length array type.

This is probably because Initializers have to be constant expressions. Constant expression have a definite value at compile time.

A {0} is an incomplete Initializer and the compiler would fill up the remaining values with 0.

If you have a VLA the compiler does not know the length of the Array and thus can not generate the initializer for it.

Kami Kaze
  • 2,069
  • 15
  • 27
-1

This depends on your compiler actually. In old C You couldn't have variable size arrays. In function fun you use a as an array with variable size n. This is not allowed in old C. However, C99 and C11 standards support variable size arrays, so perhaps you have an old compiler. (DevC?) If you want to use some type of variable arrays in older C compilers, you have to use malloc and free.

Perhaps you wanted to write this code in C++? C++ doesn't support variable size arrays also, but the gcc compiler can run this code.

Check this out: Why aren't variable-length arrays part of the C++ standard?

If you are using DevC, I think that if you change your file from test.c to test.cpp this code will work.