0

I have declared this function:

PyObject * A::func(const void *data) const {
    const time_t *time = reinterpret_cast<const time_t *>(data);
    std::tm *now = std::gmtime(time);
    PyObject *date_py = PyDate_FromDate(static_cast<int32_t>(now->tm_year + 1900), static_cast<int32_t>(now->tm_mon + 1),
                                        static_cast<int32_t>(now->tm_mday));
    PyObject_Print(date_py, stdout, 0);
    return date_py;
}

All the parameters that i use in PyDate_FromDate are int, but after calling this function and printing the date_py pyobject the result is null, like if I never created the object.

EDITED: data is a pointer to an int, in the test i'm running now->tm_year = 100, now->tm_mon = 6 and now->tm_mday = 2

What is the problem here?

  • Why are you increasing `tm_year` by 1900? What's the content of the `data`? – NutCracker Feb 06 '20 at 09:28
  • I already edited the question – Andrew Fells Feb 06 '20 at 09:33
  • You should not `reinterpret_cast` here. You should `static_cast`. Also casting to `time_t*` when the pointer is really to an `int` is potentially an aliasing violation. Why are you taking a `void*` in the first place? The `static_cast`s inside the `PyDate_FromDate` arguments seem redundant. The members of `now` are already of type `int`. – walnut Feb 06 '20 at 09:35
  • You should also test whether `std::gmtime` returns a null pointer, since it can do that on failure. – walnut Feb 06 '20 at 09:40
  • I'm using a void* because i have other functions with the same name but different class, so the behaviour in each one differs – Andrew Fells Feb 06 '20 at 09:41
  • @AndrewFells I don't understand how having multiple functions with the same name requires using `void*`. – walnut Feb 06 '20 at 09:43
  • because sometimes the content of the pointer will change to different types (string, float.. ) so the behaviour in each function will be different, i thought that if i use void * will be easier for the implementation – Andrew Fells Feb 06 '20 at 09:46
  • 1
    @AndrewFells I still don't understand. Maybe you should add an example to your question. You *must* cast the `void*` pointer back to the type that you passed to the function. Almost everything else will cause undefined behavior when you try to use the pointer. That means the function must know what type you passed it. But if the function must know that, then it can just take the correct type directly as parameter. – walnut Feb 06 '20 at 09:49
  • In your example here, the argument passed to `func` must be identical to `std::time_t*` (up to const qualification). – walnut Feb 06 '20 at 09:51
  • Yes, I agree with you that what you propose is a better practice, but I still cannot figure out why if I use 3 correct int's the object cannot be created. At least, for the test im running the object should be created – Andrew Fells Feb 06 '20 at 09:56
  • `PyErr_Print()` might give you a clue that's gone wrong – DavidW Feb 06 '20 at 12:33

0 Answers0