0

I'm trying to sum all the numbers from a file by storing numbers in an array then sum the array elements. However, the compiler says

during RTL pass: ira
/home/ubuntu/CLionProjects/printnum/main.c: In function ‘main’:
/home/ubuntu/CLionProjects/printnum/main.c:32:1: internal compiler error: Bus error
 }
 ^
cc: internal compiler error: Bus error signal terminated program cc1

What is wrong?

    int main(int argc, char *argv[])
    {
    FILE *fp;
    double tmp;
    double num[10],sum;
    int count = 0,i;

    fp = fopen("numbers.txt", "r");

    if (fp != NULL)
    {

        while (fscanf(fp, "%lf", &tmp) != EOF)
        {
            num[count++] = tmp;

        }
    }
    else {
        printf("xxxxxxx");
    }

    for ( i = 0 ; i <= sizeof(num);i++) {
        sum += num[i];
        printf("%lf", sum);
    }

    fclose(fp);
    }

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
  • An ICE (internal compiler error) is unusual — compilers do their utmost not to crash despite whatever garbage they are given to work with. That you've managed to make one crash at all is unusual. – Jonathan Leffler Sep 01 '19 at 22:10
  • You don't have 32 lines in your code — you omitted `#include ` and a blank line after it; anything else? The line `for ( i = 0 ; i <= sizeof(num);i++) {` is problematic; the loop will access 81 elements of `num`, but it only has 10. The `sizeof` operator gives the size in bytes, not the number of elements in an array. It shouldn't be a factor in the ICE, but funnier things have been known. The idiom in C for iterating over N elements of an array is `for (int i = 0; i < N; i++)` (using `<` and not `<=`). And here you can use `enum { N = sizeof(num) / sizeof(num[0]) };` for N. – Jonathan Leffler Sep 01 '19 at 22:15
  • You don't initialize `sum` to zero; you need to. – Jonathan Leffler Sep 01 '19 at 22:18
  • @JonathanLeffler I'm courious, why `enum { N = ... }` instead of a simple `const size_t n = ...`? – Marco Bonelli Sep 01 '19 at 22:18
  • @MarcoBonelli — Because `enum` is an integer constant and `const size_t N` is not an integer constant, even though it is constant integer. See [`static const` vs `#define` vs `enum`](https://stackoverflow.com/questions/1674032/static-const-vs-define-vs-enum/1674459#1674459) for a fairly thorough disquisition on the topic. Your proposed `n` can't be used in `case n:`; my `N` can be used in `case N:` — for instance. – Jonathan Leffler Sep 01 '19 at 22:20
  • @JonathanLeffler I know that, but in this case it doesn't make any difference, or am I missing something? Thanks for the link btw that's a good reference. – Marco Bonelli Sep 01 '19 at 22:23
  • @MarcoBonelli — I didn't say it made a difference here; I just use `enum` by default because it generates integer constants. I don't entirely trust/like constant integers; they're really not very helpful in C, largely because they were grafted on long after most of the rest of C was reasonably stable. I'm curious: why are you so upset that I used an `enum` instead of your preferred notation? – Jonathan Leffler Sep 01 '19 at 22:25
  • @MarcoBonelli — Of course, the whole issue would have been a non-issue if a named constant had been used for the dimension of `num` instead of the literal `10`; then the loop would use the same named constant. And, of course, the array is unnecessary; the `tmp`, `sum` and `count` variables are sufficient to solve the problem, and avoid issues with array overflow altogether. But that's tangential to the problem that this code apparently causes an ICE. That it causes an ICE is puzzling. – Jonathan Leffler Sep 01 '19 at 22:29
  • @JonathanLeffler not upset at all! I was just curious and took the chance to ask why you would suggest `enum` over `const`, since I can tell you definitely know more than me from your profile. – Marco Bonelli Sep 01 '19 at 22:29
  • 1
    @JonathanLeffler *"That it causes an ICE is puzzling."* well, that is for sure. – Marco Bonelli Sep 01 '19 at 22:31
  • You further don't protect the bounds of `num`. You only have `10` elements, but you can read an unlimited number of elements with `while (fscanf(fp, "%lf", &tmp) != EOF)` and if the conversion to `double` fails due to a *matching-failure*, you continue to blindly assign the indeterminate `tmp` to `num`. You need `while (count < 10 && fscanf(fp, "%lf", &tmp) == 1)`. The same applies to `for ( i = 0 ; i <= sizeof(num);i++)` which uses `<= sizeof(num)` where it should use `< count`. This is in addition to the comments about the uninitialized `sum` above. – David C. Rankin Sep 02 '19 at 06:32

2 Answers2

0

Several issues:

  • sizeof(num) evaluates to the number of bytes in num, not the number of elements. To get the number of elements, you can use sizeof num / sizeof num[0]. Alternately, use a symbolic constant (macro or enumeration constant) for the array size.

  • Arrays in C are indexed from 0 to N-1, so you’d want to use i < sizeof num / sizeof num[0], not <=.

  • sum needs to be initialized to 0 before you start adding.

Is there any particular reason why you want to store the values in an array before computing the sum? What if you have a file with more than 10 elements in it? Why not just add to the sum as you read values from the file?

John Bode
  • 119,563
  • 19
  • 122
  • 198
0

Compilers are large and complicated. Sometimes they have bugs. Sometimes the bugs cause them to access something they shouldn't (e.g. the tenth element in an array of 4 elements), and sometimes this is detected by the CPU/kernel/OS and results in a SIGSEGV or "bus error".

It is never supposed to happen (compilers aren't supposed to have bugs); and (even if you try to compile "/dev/random"), it should either correctly compile or correctly tell you why it couldn't compile (and should never crash and should never tell you it had an internal compiler error).

To resolve the issue; check to see if there's a newer version of your compiler, and if there isn't check to see if the bug has been reported to the compiler's developers already, and if it hasn't report the bug to the compiler's developers.

Brendan
  • 35,656
  • 2
  • 39
  • 66