Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. Other Discussions
  3. Clever Code
  4. dynamic_cast changed behavior in VS5

dynamic_cast changed behavior in VS5

Scheduled Pinned Locked Moved Clever Code
helpcsharpc++visual-studiooop
7 Posts 3 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • A Offline
    A Offline
    Ami Bar
    wrote on last edited by
    #1

    I got into this case during migration of C++ code from VS03 to VS05. class BaseClass { ... }; class DerivedClass : BaseClass { ... }; Very simple code, when you'll try to cast DerivedClass to BaseClass: DerivedClass *d = new DerivedClass(); BaseClass *b = d; The compiler will fail with an error. (Stop here and try to understand why) Gave up, the compiler will fail with and error: error C2243: 'type cast' : conversion from 'DerivedClass *' to 'BaseClass *' exists, but is inaccessible. If you will try to do: DerivedClass *d = new DerivedClass(); BaseClass *b = dynamic_cast(d); The compiler will show a warning: warning C4540: dynamic_cast used to convert to inaccessible or ambiguous base; run-time test will fail ('DerivedClass *' to 'BaseClass *') The reason for this is that the default inheritance access is private, this means that DerivedClass definition is equal to: class DerivedClass : **private** BaseClass { ... }; Which means that DerivedClass cannot be cast to BaseClass. To fix this we need to change the code and explicitly state that the derivation is public: class DerivedClass : **public** BaseClass { ... }; It is little complicated to show it here, but you can build a code that uses the dynamic_cast and doesn't show the warning or an error. It involves in using a dll that implements the classes, and an exe that uses these classes with forward declaration, and a virtual clone method, very ugly, but this is how our code is written. Now I am getting to the point. Assume you have code like the following, that doesn't show any error or warning during compilation. BaseClass *foo(DerivedClass *d) { BaseClass *b = dynamic_cast(d); return b; } When this code is compiled with Visual Studio 2003, d will be cast to the BaseClass successfully at run-time and b will be a valid pointer. When this code is compiled with Visual Studio 2005, b will be NULL at run-time. For years we didn't see that there was a missing 'public' in that inheritance, because everything worked. Note that the original application doesn't rely on the dynamic_cast, it only uses it in an assert statement to check that a casting is correct.

    M S 2 Replies Last reply
    0
    • A Ami Bar

      I got into this case during migration of C++ code from VS03 to VS05. class BaseClass { ... }; class DerivedClass : BaseClass { ... }; Very simple code, when you'll try to cast DerivedClass to BaseClass: DerivedClass *d = new DerivedClass(); BaseClass *b = d; The compiler will fail with an error. (Stop here and try to understand why) Gave up, the compiler will fail with and error: error C2243: 'type cast' : conversion from 'DerivedClass *' to 'BaseClass *' exists, but is inaccessible. If you will try to do: DerivedClass *d = new DerivedClass(); BaseClass *b = dynamic_cast(d); The compiler will show a warning: warning C4540: dynamic_cast used to convert to inaccessible or ambiguous base; run-time test will fail ('DerivedClass *' to 'BaseClass *') The reason for this is that the default inheritance access is private, this means that DerivedClass definition is equal to: class DerivedClass : **private** BaseClass { ... }; Which means that DerivedClass cannot be cast to BaseClass. To fix this we need to change the code and explicitly state that the derivation is public: class DerivedClass : **public** BaseClass { ... }; It is little complicated to show it here, but you can build a code that uses the dynamic_cast and doesn't show the warning or an error. It involves in using a dll that implements the classes, and an exe that uses these classes with forward declaration, and a virtual clone method, very ugly, but this is how our code is written. Now I am getting to the point. Assume you have code like the following, that doesn't show any error or warning during compilation. BaseClass *foo(DerivedClass *d) { BaseClass *b = dynamic_cast(d); return b; } When this code is compiled with Visual Studio 2003, d will be cast to the BaseClass successfully at run-time and b will be a valid pointer. When this code is compiled with Visual Studio 2005, b will be NULL at run-time. For years we didn't see that there was a missing 'public' in that inheritance, because everything worked. Note that the original application doesn't rely on the dynamic_cast, it only uses it in an assert statement to check that a casting is correct.

      M Offline
      M Offline
      Mauro Leggieri
      wrote on last edited by
      #2

      I think that you had that problem because VS2005 is supposed to be more compatible with the ansi c++ standards, and by default, base classes specified in "class" are private and base classes specified in "struct" are public. Best regards, Mauro H. Leggieri

      A 1 Reply Last reply
      0
      • M Mauro Leggieri

        I think that you had that problem because VS2005 is supposed to be more compatible with the ansi c++ standards, and by default, base classes specified in "class" are private and base classes specified in "struct" are public. Best regards, Mauro H. Leggieri

        A Offline
        A Offline
        Ami Bar
        wrote on last edited by
        #3

        My bug was not revealed, because Microsoft missed a check. In VS05 they fixed it. Ami

        1 Reply Last reply
        0
        • A Ami Bar

          I got into this case during migration of C++ code from VS03 to VS05. class BaseClass { ... }; class DerivedClass : BaseClass { ... }; Very simple code, when you'll try to cast DerivedClass to BaseClass: DerivedClass *d = new DerivedClass(); BaseClass *b = d; The compiler will fail with an error. (Stop here and try to understand why) Gave up, the compiler will fail with and error: error C2243: 'type cast' : conversion from 'DerivedClass *' to 'BaseClass *' exists, but is inaccessible. If you will try to do: DerivedClass *d = new DerivedClass(); BaseClass *b = dynamic_cast(d); The compiler will show a warning: warning C4540: dynamic_cast used to convert to inaccessible or ambiguous base; run-time test will fail ('DerivedClass *' to 'BaseClass *') The reason for this is that the default inheritance access is private, this means that DerivedClass definition is equal to: class DerivedClass : **private** BaseClass { ... }; Which means that DerivedClass cannot be cast to BaseClass. To fix this we need to change the code and explicitly state that the derivation is public: class DerivedClass : **public** BaseClass { ... }; It is little complicated to show it here, but you can build a code that uses the dynamic_cast and doesn't show the warning or an error. It involves in using a dll that implements the classes, and an exe that uses these classes with forward declaration, and a virtual clone method, very ugly, but this is how our code is written. Now I am getting to the point. Assume you have code like the following, that doesn't show any error or warning during compilation. BaseClass *foo(DerivedClass *d) { BaseClass *b = dynamic_cast(d); return b; } When this code is compiled with Visual Studio 2003, d will be cast to the BaseClass successfully at run-time and b will be a valid pointer. When this code is compiled with Visual Studio 2005, b will be NULL at run-time. For years we didn't see that there was a missing 'public' in that inheritance, because everything worked. Note that the original application doesn't rely on the dynamic_cast, it only uses it in an assert statement to check that a casting is correct.

          S Offline
          S Offline
          Sergio Zykov
          wrote on last edited by
          #4

          You should derive this class in this way class DerivedClass : public BaseClass { ... }; By default, the inheritance of 'class' symbols are private and, according to C++ standard, the derived class is not a sublass of its privately inherited superclass. In different words, private inhertance is the inheritance of the base class' implementation and public inheritance is the inheritance of the base class' interface.

          A 1 Reply Last reply
          0
          • S Sergio Zykov

            You should derive this class in this way class DerivedClass : public BaseClass { ... }; By default, the inheritance of 'class' symbols are private and, according to C++ standard, the derived class is not a sublass of its privately inherited superclass. In different words, private inhertance is the inheritance of the base class' implementation and public inheritance is the inheritance of the base class' interface.

            A Offline
            A Offline
            Ami Bar
            wrote on last edited by
            #5

            I already know what should be done. The point is the behavior of the dynamic_cast. Ami

            S 1 Reply Last reply
            0
            • A Ami Bar

              I already know what should be done. The point is the behavior of the dynamic_cast. Ami

              S Offline
              S Offline
              Sergio Zykov
              wrote on last edited by
              #6

              Sorry, i've missed the second half of your posting. Anyway, the old behaviour should be considered as a bug, not a new one.

              A 1 Reply Last reply
              0
              • S Sergio Zykov

                Sorry, i've missed the second half of your posting. Anyway, the old behaviour should be considered as a bug, not a new one.

                A Offline
                A Offline
                Ami Bar
                wrote on last edited by
                #7

                Correct. Ami

                1 Reply Last reply
                0
                Reply
                • Reply as topic
                Log in to reply
                • Oldest to Newest
                • Newest to Oldest
                • Most Votes


                • Login

                • Don't have an account? Register

                • Login or register to search.
                • First post
                  Last post
                0
                • Categories
                • Recent
                • Tags
                • Popular
                • World
                • Users
                • Groups