5
votes

The following code is derived from a question here. (I am aware there are several logical problems with the code, but I do not understand how they are causing this problem.)

Edit: I am using CLANG on Windows, with common warning displayed for compile.

It generates a Divide by zero fault at the indicated line (first statement in the for loop.), but there are no apparent divides. Can anyone please provide some insight on why this error occurs?

Edit 2: Per comments: changing the 3rd argument in the sepia function from

void sepia(int height, int width, RGBTRIPLE image[height][width])

to

void sepia(int height, int width, RGBTRIPLE image[3][4])

eliminates the divide by zero error. Why?

typedef struct {
    double rgbtRed;
    double rgbtGreen;
    double rgbtBlue;
}RGBTRIPLE;

RGBTRIPLE image[3][4];

void sepia(int height, int width, RGBTRIPLE image[height][width])
{
    double sepiaRed = 0.0;
    double sepiaGreen = 0.0;
    double sepiaBlue = 0.0;
    // over height
    for (int h = 0; h < height; h++)
    {
        // over width
        for ( int w = 0; w < width; w++)
        {
            sepiaRed = .393 *  image[h][w].rgbtRed + .769 *  image[h][w].rgbtGreen + .189 *  image[h][w].rgbtBlue;
                           //  ^ Divide by zero occurs on this line.
            sepiaGreen = .349 *  image[h][w].rgbtRed + .686 *  image[h][w].rgbtGreen + .168 *  image[h][w].rgbtBlue;
            sepiaBlue = .272 *  image[h][w].rgbtRed + .534 *  image[h][w].rgbtGreen + .131 *  image[h][w].rgbtBlue;
            // space
            if (sepiaRed > 255 || sepiaGreen > 255 || sepiaBlue > 255)
            {
                sepiaRed = 255;
                sepiaGreen = 255;
                sepiaBlue = 255;
            }

            image[h][w].rgbtRed = (sepiaRed);
            image[h][w].rgbtBlue = (sepiaBlue);
            image[h][w].rgbtGreen = (sepiaGreen);
        }
    }
   return;
}

int main()
{
    sepia(3, 4, image);

    return 0;
}
1
Works fine for me. What compiler and options are you using? Are you sure you are not mixing executables? Most probably you are running a executable that is out-of-sync with the source file. - KamilCuk
@Mathieu — the image array is global; it is zeroed. - Jonathan Leffler
Perhaps code is not handling the VLA correctly (div 0 coming from indexing) Try RGBTRIPLE image[height][width] --> RGBTRIPLE image[3][4] - chux - Reinstate Monica
Unfortunately, I have not yet produced assembly with this compiler implementation. It is packaged in an NI ANSI C environment along with the default NI compiler, not sure I can even produce the assmbly. I will try the NI compiler, and also a GCC compiler I have to see if results are same. , if it exhibits the same behavior, I will post the assembly. - ryyker
@ryyker Your local image in sepia is shadowing your global image. May be acceptable as you're using a pointer (array). - Fiddling Bits

1 Answers

3
votes

Division by 0 due to array indexing.

Either VLA support is faulty or non-existent.

//                         VLA prototype         v-------------v           
void sepia(int height, int width, RGBTRIPLE image[height][width]) {
        //                      v----v
        sepiaRed = .393 *  image[h][w].rgbtRed + .769 *  ...

Code can use a non-VLA approach as below,

void sepia(int height, int width, RGBTRIPLE image[3][4]) {

VLA support begins with C99.

With C11 or later, check __STDC_NO_VLA__ for non-support.