locked
A Hole in the C++ Type System RRS feed

  • Question

  • C++ permits automatic type conversions

    • T[n] → T*
    • D* → B* if D is a derived class with base class B

    Each of these is useful. The first conversion allows programmers to implement functions that operate on arrays:

    void process(T* a, int n) // Processes arrays of type T of any size

    The second conversion allows programmers to implement polymorphic functions:

    void process(B* p) // Processes an element of type B or some subtype of B 

    When these conversions are combined, the result is unsound. (That is, you can write programs that compile and run without type errors and that corrupt objects at run time.) Explain why, and give an example program that demonstrates the problem.

    Sunday, November 21, 2010 4:06 PM

Answers

  • Hi,

    Your answer just got the posting up. It is an interesting question and the problem is quite easy.

    In an array, you have objects of a defined size one after another so you get something like
    (obj1)(obj2)(obj3)(obj4)....
    and to access the nth object, internally something is done like:
    pointer + (n-1)*size(obj)

    (So the array and the pointer can both be exchanged (rule 1).

    The 2nd rule now tells the system, that you can use the derived class instead. Example can be: You have a class vehicle and a derived class lorry. Now you create an array of lorries, just take the pointer to that array and now cast it to vehicles. Now I expect it to take the size of vehicles but that is the wrong size so the boundaries are incorrect.

    I think that should be the problem and a reason why managed languages are used widely (Java, .Net Framework with its languages and even Apple with Objective-C starts to go the managed way!) because they check boundaries completly and do not allow any access to memory (so all these buffer overflow attacks and stuff like that are no longer possible).

    With kind regards,

    Konrad

    • Marked as answer by Rubel Khan Monday, December 20, 2010 3:51 AM
    Friday, December 10, 2010 7:49 AM
    Answerer

All replies

  • This is not the right forum. Please post a question if it’s related IT Training and Certification (Specially Microsoft).

    Here is the list all others forums. http://social.msdn.microsoft.com/Forums/en/categories

    Hope this is helpful.


    Rubel Khan

    My Blog!
    My Podcast!
    Connect with me at LinkedIn
    Follow me on Twitter!
    Thursday, December 9, 2010 9:05 PM
  • Hi,

    Your answer just got the posting up. It is an interesting question and the problem is quite easy.

    In an array, you have objects of a defined size one after another so you get something like
    (obj1)(obj2)(obj3)(obj4)....
    and to access the nth object, internally something is done like:
    pointer + (n-1)*size(obj)

    (So the array and the pointer can both be exchanged (rule 1).

    The 2nd rule now tells the system, that you can use the derived class instead. Example can be: You have a class vehicle and a derived class lorry. Now you create an array of lorries, just take the pointer to that array and now cast it to vehicles. Now I expect it to take the size of vehicles but that is the wrong size so the boundaries are incorrect.

    I think that should be the problem and a reason why managed languages are used widely (Java, .Net Framework with its languages and even Apple with Objective-C starts to go the managed way!) because they check boundaries completly and do not allow any access to memory (so all these buffer overflow attacks and stuff like that are no longer possible).

    With kind regards,

    Konrad

    • Marked as answer by Rubel Khan Monday, December 20, 2010 3:51 AM
    Friday, December 10, 2010 7:49 AM
    Answerer
  • Ohh ... I was completly wrong of course! Shame on my head. I had a discussion with a colleague who is a guru wth c++ / COM and all things arouind software development on windows and first he asked for the business requirements behind that questions and told be to go and get a life :).

    An array with instances of classes will be of course an array with pointers to the different instances and these instances are somewhere on the heap and the size for each element in the array is exactly the size of a pointer.

    So it could only be a problem if you have structs (what is called value types in .Net). So at least we know, that my first idea was simply wrong and that I have to go and get a life instead of thinking about such questions :)

    With kind regards,

    Konrad

    Friday, December 10, 2010 10:11 AM
    Answerer