Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Compiler warning for mixed array and polymorphism

In More Effective C++, an interesting point brought up is that mixing array's and polymorphism is a bad idea. For eg:

class Base {
    public:
    Base(int y) : a(y) {}
    int a;
};

class D : public Base {
    public:
    D(int w, int y) : Base(y), c(w) {}
    int c;
};

std::ostream& operator<<(std::ostream& os, const Base &obj )
{
    os << obj.a << std::endl;
    return os;
}

// This function will work perfectly well if i pass in a `Base` array, 
// but if i pass in `D` array we are going to run into some problems. 
// Namely that `arr[i+1] = &arr[i] + sizeof(Base)` will not progress 
// the array correctly for a `D` array.
void printArray(const Base arr[]) {
    for (int i = 0; i < 5; ++i) {
        std::cout << arr[i];
    }
}

int main() {
   D arr[5] = { D(0, 10), D(1, 11), D(2, 12), D(3, 13), D(4, 14)};
   printArray(arr); // This compiles without complaint! I understand that the
                    // conversion is legal, but it seems like a warning
                    // about this would be a good idea. 
}

Note: I know this is bad design but is to illustrate a point.

The problem here is that when mixing these two in the way i have above, when we iterate through the array to print we will not progress the element of the array by the correct amount (ie we move by sizeof(Base) instead of sizeof(D)). This results in the output:

10
0
11
1
12

[Live example.]

(And i am guessing that calling the operator<< like this is probably UB).

When compiling with g++ -std=c++1y -Wall -Weffc++ -pedantic main.cpp I get no warnings or errors.

  1. Is there a compiler flag that I can enable that indicates a warning in this scenario?
  2. If not, why not?
like image 227
Fantastic Mr Fox Avatar asked Oct 30 '22 20:10

Fantastic Mr Fox


1 Answers

A compiler could do a lot of static analyzing, and could know that the pointer arr in the function is used as an array with unexpected results.

However, doing that is slow and uses a lot (more) of memory, and programmers are generally impatient and want their compilations to be done as quick as possible using as little other resources as possible too. Therefore most compilers only do static analyzes that are relatively quick and easy, leaving the hard work to dedicated static analyzers.

like image 63
Some programmer dude Avatar answered Nov 13 '22 08:11

Some programmer dude