On 8/14/2018 10:38 AM, Radosław Korzeniewski wrote:
Hello,

2018-08-14 14:08 GMT+02:00 Josh Fisher <jfis...@pvct.com <mailto:jfis...@pvct.com>>:


    On 8/14/2018 6:56 AM, Martin Simmons wrote:

        Sorry to say that it doesn't compile on FreeBSD (see below).

        The warnings about BSOCK::recv are probably generic and occur
        in every file.

        There is some hack for ENODATA in bsockcore.c, but not in bsock.c.



        Compiling bsock.c
        In file included from bsock.c:35:
        In file included from ../bacula.h:169:
        In file included from ../lib/lib.h:51:
        ./bsock.h:72:12: warning: 'BSOCK::recv' hides overloaded
        virtual function [-Woverloaded-virtual]
            int32_t recv();


    Don't know about the missing ENODATA in BSD, but the warning
    should be checked out.

    This warning is where class A defines a virtual function, then
    class B, derived from A, overrides it,


Yes, this is a case here.

    then class C, derived from B, overrides it again, but doesn't
    override all versions.


We have no class C here.

In that case, there is a pure virtual function in the base class that is not being defined anywhere. Given the class A from the previous example, and class B defined as:

class B : public A
{
   virtual bool isvalid(char c) { return c > 0; }
};

There is a pure virtual function, (A::isvalid(int32_t val) = 0), for which no function definition exists in either class A or B. Since isvalid(char) is overridden in B, the isvalid(char) version will always be used. This is why it is a warning instead of an error. The warning is because if the base class defined different versions of the pure virtual function for different argument types, then there could well be a good reason for doing so. For example, if the isvalid(char) function is called with a int32_t argument there will be an implied conversion from int32_t to char. This can cause strange errors that are hard to track down. A better example would be if class A defined pure virtual functions  isvalid(unsigned int) and isvalid(int), but class B only overrode one of them. An unsigned int argument passed to the isvalid(int) function would cause an erroneous result if it were large enough that the unsigned int to signed int conversion made it convert to a negative value.


    Easier to explain by example.

    class A
    {
    public:
      virtual bool isvalid(int32_t val) = 0;
      virtual bool isvalid(char c) = 0;
    };

    class B : public A
    {
    public:
      virtual bool isvalid(int32_t val) { return c < 0; }
      virtual bool isvalid(char c) { return c < 0; }
    };


It could be out case.

    class C : public B
    {
      virtual bool isvalid(char c) { return c > 0; }
    };


No, we do not have a class C.

    In class C, there is no isvalid(int32_t val) implementation, so
    consider the following:

    bool some_func()
    {
       C use_it;
       int32_t val = 1;

       return C.isvalid(val);
    }

    The some_func() function will return TRUE, not the expected FALSE.
    This is because the B::isvalid(int32_t) override is hidden to C,
    hence the warning. C::isvalid() will always be evaluated as the
    single isvalid() override defined in C.

    For sane behavior, where B's overrides of isvalid() are NOT
    hidden, define C as:

    class C : public B
    {
    public:
       virtual bool isvalid(char c) { return c > 0; }
       using B::isvalid;

    };


Could you check our case where we have class A and class B but not class C. Thanks.

best regards
--
Radosław Korzeniewski
rados...@korzeniewski.net <mailto:rados...@korzeniewski.net>

------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
Bacula-devel mailing list
Bacula-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/bacula-devel

Reply via email to