2
votes

does anyone know, why the following codes is crashing, when it is compiled with g++?

#include <iostream>

unsigned long getSumDivisors(const unsigned long number) {
    unsigned long sum = 0;
    for(unsigned long i = 0; i < number; ++ i) {
        if(number % i == 0) {
            sum += i;
        }
    }
    return sum;
}

int main() {
    std::cout << getSumDivisors(5);
    return 0;
}

when i remove sum += i; it wont crash.

I tried to compile it under windows and linux linaro with

g++ (Ubuntu/Linaro 4.7.3-1ubuntu1) 4.7.3 Copyright © 2012 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

and

g++ (tdm-2) 4.8.1 Copyright (C) 2013 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

4
It crashes during compile or after you run the program? You have a divide by zero error which is undefined behavior.Shafik Yaghmour

4 Answers

5
votes

It causes an SIGFPE. The reason is because of the division by zero:

if(number % i == 0)

You can fix it here:

 for(unsigned long i = 1; i < number; ++ i)

The SIGFPE will be happening usually on systems with a floating point unit, which raises an exception in this case. The actual behaviour depens on the implmentation details and is undefined. On older systems with an floating point emulation library it may return 0 or or a random result.

3
votes

You are dividing by 0 because i is initiated with 0 in the for loop and then you try and get the left-over of the division

2
votes

The first time through the loop, you have i = 0. You can't divide by zero, so your "number % i" is bad. It appears on your system that's causing a crash.

I wonder if removing "sum += i" causes some sort of optimization such that the if condition is never checked because of the empty body.

1
votes

This will not crash during compilation (see it live) but you do have undefined behavior here:

if(number % i == 0) {
          ^^^

since i starts at 0 and modulus by zero is undefined. This is covered in the draft C++ standard section 5.6 Multiplicative operators paragraph 4:

[...]If the second operand of / or % is zero the behavior is undefined.[...]

This means anything can happen, that includes a crash and in fact if I use the -O3 flag it no longer crashes on Coliru (see it live). Which is also perfectly acceptable undefined behavior.