Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

no warning for pointer to subclassed struct of wrong size

Tags:

c++

I was writing a helper class to concisely initialize struct pollfds, and lamenting that I could not add an additional member in the helper subclass class, so I tried and to my surprise it compiled without any warnings. The runtime behavior is wrong as I expected, but why can I even get this far?

I would expect pointers to classes of different sizes to at least a require a cast; is there a compiler flag that will detect this error? I'm compiling with g++ 9.4.0, no additional flags specified.

Code:

#include <poll.h>
#include <vector>

struct pollin : public pollfd {
    int extra;  ///< additional field in derived class.
    pollin(int infd) {
        fd = infd;
        events = POLLIN;
    }
};


int main(int ac, char **av) {
    std::vector<pollin> fds;
    fds.emplace_back(5);
    fds.emplace_back(6);
    poll(fds.data(), fds.size(), 0);
    return 0;
}

The as-expected wrong runtime behavior can be seen by running with strace:

poll([{fd=5, events=POLLIN}, {fd=0, events=POLLPRI|POLLOUT}], 2, 0) = 2 ([{fd=5, revents=POLLNVAL}, {fd=0, revents=POLLOUT}])
like image 482
evil otto Avatar asked Nov 29 '25 17:11

evil otto


1 Answers

As long as you don't try to offset from it, a pointer to a derived class can be directly substituted for a pointer to its parent without a cast. This is the standard practice to allow for polymorphism. In fact, if you had done poll(fds.data(), 1, 0) everything would have worked and been well-defined.

Its when you try to treat a pointer to the first element of an array of derived objects like a pointer to the first element of an array of parent objects that you run into problems. The two are not interchangeable in that situation.

The issue here is that the compiler has no idea what poll does. When it's compiling your main function all it sees is poll's signature, so it doesn't know that poll will treat the pointer you passed it as pointing to the first element of an array.


I'm actually quite surprised that none of the major compilers offer a warning for using a pointer to the first element of an array of derived objects as a pointer to the first element of an array of parent objects, even when everything is easily visible.

like image 102
Miles Budnek Avatar answered Dec 02 '25 06:12

Miles Budnek



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!