Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CHECK_RANGE macro attempts to pass Rcomplex value to %f formatter #6531

Open
MichaelChirico opened this issue Sep 24, 2024 · 1 comment
Open

Comments

@MichaelChirico
Copy link
Member

Seen as part of #6530, where an ad hoc solution to use val.r instead of val is used to unblock that PR.

AFAICT this is not strictly a bug because snprintf() is currently doing this (using val.r) implicitly:

DT=data.table(a = 1:10)
set(DT, 2L, 'a', 1+2i)
# Warning message:
# In set(DT, 2L, "a", 1 + (0+2i)) :
#   1.000000 (type 'complex') at RHS position 1 either imaginary part discarded or real part truncated (precision lost) when assigning to type 'integer' (column 1 named 'a')

set(DT, 2L, 'a', 1+3i)
# Warning message:
# In set(DT, 2L, "a", 1 + (0+3i)) :
#   1.000000 (type 'complex') at RHS position 1 either imaginary part discarded or real part truncated (precision lost) when assigning to type 'integer' (column 1 named 'a')

set(DT, 2L, 'a', 0+3i)
# Warning message:
# In set(DT, 2L, "a", 0 + (0+3i)) :
#   0.000000 (type 'complex') at RHS position 1 either imaginary part discarded or real part truncated (precision lost) when assigning to type 'integer' (column 1 named 'a')

But I believe the error message is not correct/as helpful as it could be if constructed more carefully.

@aitap
Copy link
Contributor

aitap commented Sep 24, 2024

We've been lucky that giving a struct instead of a double didn't damage the stack. On a 32-bit platform this could have crashed:

#include <stdio.h>

typedef union {
    struct {
        double r;
        double i;
    };
    double _Complex private_data_c;
} Rcomplex;


int main(void) {
        Rcomplex foo = { .r = 1, .i = 2 };
        printf("%f should be 1, %s should be 1\n", foo, "1");
}
$ gcc -m32 -o ex ex.c && ./ex
1.000000 should be 1, (null) should be 1

The standard says it's undefined behaviour because the expected and the given types don't match.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants