-3

In the following code, it works with the size of array (As written while defining the arrays arr and brr ) k/n (or k/m) as well as n/k (or m/k). I'm a beginner in C++ and according to my knowledge, size of an array must be an integer greater than zero. But here this statement goes wrong.

I've tried changing the length of an array to 0 due to the logic that n/k is not an integer and since c++ converts it to 0, writing 0 in place of n/k should be equivalent. But it isn't.

Also, when I run the code by asking the user for values of k,n,m instead of defining it in the source code itself, the code runs only when I write - n/k and m/k - k/n and m/k

And it shows the error "program.exe has stopped working. Windows is checking for a solution to the problem." when I have k/m irrespective that I have n/k or k/n.

I have tried using the debugger too (I'm using Codeblocks) but it did not give me any idea to why is the program still being executed when n/k is not an integer.

#include <iostream>

using namespace std;




int main()
{   int k=9;
    int n=2;
    int m=3;

    int arr[n/k];
    int brr[m/k];


    for(int i=0;i<k/n;i++)
    {int x= n*(i+1);
    arr[i]=x;

    }

    for(int j=0; j<k/m; j++)
    {
        int y= m*(j+1);
        brr[j]=y;
    }

    cout << "\n";

    for(int i=0;i<k/n;i++)
    {
        cout<< arr[i] <<"\n";
    }

    cout << "\n";

    for(int j=0; j<k/m; j++)
    {
        cout<< brr[j] <<"\n";
    }
    return 0;
}

As much as I know, the code should not work in case we write n/k and m/k. But it is. Why?

Note- this code was written to solve https://www.geeksforgeeks.org/count-common-elements-in-two-arrays-containing-multiples-of-n-and-m/ (though I have not completed writing the code to solve the problem fully)

Edit- As many comments have pointed out and given links to answers that explain why n/k is an integer (by integer division), I would like to clarify that the question is not that why n/k is rounded to an integer. The questions are

  1. Why are n/k and k/n given same value in integer division (they aren't the same obviously but as the program works fine for both of them, they seem to be equivalent. Why is it so?)

    1. Yes n/k is integer division. So the answer should be 0 (because 2/9 would be truncated to 0). But when we replace n/k by 0, the code doesn't work.
user185887
  • 643
  • 6
  • 18
  • 2
    Maybe a duplicate? It's for C, not for C++, though: https://stackoverflow.com/q/3602827/1896169 – Justin Jul 03 '19 at 19:10
  • 1
    "the program still being executed when n/k is not an integer" but `n/k` is **always** an integer when `n` and `k` are both integers. – alter_igel Jul 03 '19 at 19:10
  • As for why `n/k` is an integer, https://softwareengineering.stackexchange.com/q/307993/184655 helps to explain – Justin Jul 03 '19 at 19:11
  • 4
    Also note that C++ doesn't really have [variable-length arrays](https://en.wikipedia.org/wiki/Variable-length_array). Some compilers add it as a non-standard and non-portable extension. – Some programmer dude Jul 03 '19 at 19:12
  • 1
    See https://stackoverflow.com/questions/7571326/why-does-dividing-two-int-not-yield-the-right-value-when-assigned-to-double – Donnie Jul 03 '19 at 19:12
  • This doesn't compile for me because `k`, `n` and `m` aren't constant expressions. If I fix that, it still doesn't compile because zero sized arrays aren't allowed. Edit : Consider the -pedantic flag. – François Andrieux Jul 03 '19 at 19:25
  • @Justin I'm okay with the fact that n/k is an integer (0 in this case). But then our program should not run. Instead it should give an error. Why does it execute? – user185887 Jul 03 '19 at 19:27
  • 1
    @user185887 See the answer below. The behavior is undefined. It can do anything, include running to completion as you expect. But the same code may behave differently on a different platform, different compiler, with different flags or just at a different time of day. Edit : In the original code, you are using variable length arrays, which follows GCC's own rules because it's not something the language offers, it's an extension. If you replace the size with 0 you now have a constant expression, it's no longer a VLA and GCC may be forced to play by the language's rules. – François Andrieux Jul 03 '19 at 19:28
  • Follow up : I wasn't able to reproduce, GCC doesn't complain if you specify the constant `0` to the arrays' size unless I add the -pedantic flag. But then it complains for both codes. – François Andrieux Jul 03 '19 at 19:30

1 Answers1

1

As much as I know, the code should not work in case we write n/k and m/k. But it is. Why?

Because n/k and m/k use integer division, which results in integer values.

As to the size of the array, the standard requires that:

it shall be an integral constant expression and its value shall be greater than zero.

When n/k or m/k is zero, the behavior is not defined by the standard. If your program seems to work, it's just that -- it is seemingly correct. In theory, it is subject to undefined behavior.

R Sahu
  • 204,454
  • 14
  • 159
  • 270
  • but that integer value is 0 (correct me if I am wrong) – user185887 Jul 03 '19 at 19:12
  • "it is seemingly correct"-- could you please elaborate what that means or how is that even possible? – user185887 Jul 03 '19 at 19:24
  • @user185887, when a program has undefined behavior, you never know what its behavior is going to be. Unfortunately, sane behavior also falls under the category of undefined behavior. Such a program might work under one set of compiler, compiler options and fail inexplicably under a different compiler or a different set of compiler options. – R Sahu Jul 03 '19 at 19:28
  • @user185887 You may be interested in reading about [Undefined Behavior](https://en.cppreference.com/w/cpp/language/ub). It's an extremely important concept for working with C++. – François Andrieux Jul 03 '19 at 19:32
  • Doesn't "shall" translate to "ill-formed" instead of "undefined behavior"? – L. F. Jul 15 '19 at 00:46