cc65: cc65 fails to warn about a function returning struct

This program gives wrong results when built on cc65, regardless of -O. The function is correct, and it succeeds when built on gcc.

(I was looking for a faster div() alternative. Still need to try a modified stdlib div() that uses unsigned division instead.)

#include <nes.h>
#include <conio.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>

typedef uint16_t u16;
typedef uint8_t u8;

typedef struct {
    u16 quot;
    u16 rem;
} udiv_t;

udiv_t div3(u16 in) {

    udiv_t u;
    u16 q = 0;

    while (in >= 300) {
        in -= 300;
        q += 100;
    }

    while (in >= 30) {
        in -= 30;
        q += 10;
    }

    while (in >= 3) {
        in -= 3;
        ++q;
    }

    u.quot = q;
    u.rem = in;

    return u;
}

int main() {

    u16 i;
    div_t d;
    udiv_t u;

    for (i = 1024; i; i--) {
        d = div(i, 3);
        u = div3(i);

        if (d.quot != u.quot || d.rem != u.rem) {
            cprintf("Mismatch at %u/3, div %u %u, div3 %u %u\n", i,
                d.quot, d.rem, u.quot, u.rem);
            break;
        }
    }

    while (1);

    return 0;
}

About this issue

  • Original URL
  • State: closed
  • Created 8 years ago
  • Comments: 30 (30 by maintainers)

Most upvoted comments

Another idea is to detect this kind of statement:

<struct_variable> = <function_returning_struct>();

Then, compiling it as though it were:

<struct_variable> = *(<function_returning_pointer_to_struct>());

If there are no C-level interrupts, then that immediate block-copy will be able to handle structs that are defined in the function as “automatic” variables.