fork download
  1. #include <iostream>
  2.  
  3. struct B1 {
  4. char x[1];
  5. };
  6.  
  7. struct B2 {
  8. char x[1];
  9. };
  10.  
  11. struct D :
  12. private B1,
  13. private B2 {
  14. char x[1];
  15. };
  16.  
  17. #define RAW_PTR static_cast<const void*>
  18.  
  19. int main()
  20. {
  21. using namespace std;
  22.  
  23. D d;
  24.  
  25. D* pd = &d;
  26.  
  27. cout << "-------" << endl;
  28. cout << "upcasts" << endl;
  29. cout << "-------" << endl;
  30. cout << endl;
  31. {
  32. //B2* p = pd; // error: 'B2' is an inaccessible base of 'D'
  33. }
  34. {
  35. //B2* p = static_cast<B2*>(pd); // error: 'B2' is an inaccessible base of 'D'
  36. }
  37. {
  38. B2* p = reinterpret_cast<B2*>(pd); // Compiles, but is wrong!
  39. // simply copies bits, doesn't adjust
  40. cout << "reinterpret_cast:" << endl;
  41. cout << pd << endl;
  42. cout << p << endl;
  43. cout << ((RAW_PTR(p) == RAW_PTR(pd)) ? "Wrong!" : "Right.") << endl;
  44. cout << endl;
  45. }
  46. {
  47. B2* p = (B2*)pd; // Correct conversion, here equivalent to
  48. // implicit conversion ignoring 'private' access specifier;
  49. // makes the needed adjustment
  50. cout << "C-style cast:" << endl;
  51. cout << pd << endl;
  52. cout << p << endl;
  53. cout << ((RAW_PTR(p) == RAW_PTR(pd)) ? "Wrong!" : "Right.") << endl;
  54. cout << endl;
  55. }
  56.  
  57. cout << endl;
  58.  
  59. B2* pb2 = (B2*)&d; // (correct conversion)
  60.  
  61. cout << "---------" << endl;
  62. cout << "downcasts" << endl;
  63. cout << "---------" << endl;
  64. cout << endl;
  65. {
  66. //D* p = pb2; // error: invalid conversion from 'B2*' to 'D*' [-fpermissive]
  67. // (then also error: 'B2' is an inaccessible base of 'D')
  68. }
  69. {
  70. //D* p = static_cast<D*>(pb2); // error: 'B2' is an inaccessible base of 'D'
  71. }
  72. {
  73. D* p = reinterpret_cast<D*>(pb2); // Compiles, but is wrong!
  74. // simply copies bits, doesn't adjust
  75. cout << "reinterpret_cast:" << endl;
  76. cout << pb2 << endl;
  77. cout << p << endl;
  78. cout << ((RAW_PTR(p) == RAW_PTR(pb2)) ? "Wrong!" : "Right.") << endl;
  79. cout << endl;
  80. }
  81. {
  82. D* p = (D*)pb2; // Correct conversion, here equivalent to
  83. // static_cast ignoring 'private' access specifier;
  84. // makes the needed adjustment
  85. cout << "C-style cast:" << endl;
  86. cout << pb2 << endl;
  87. cout << p << endl;
  88. cout << ((RAW_PTR(p) == RAW_PTR(pb2)) ? "Wrong!" : "Right.") << endl;
  89. cout << endl;
  90. }
  91. }
Success #stdin #stdout 0s 2852KB
stdin
Standard input is empty
stdout
-------
upcasts
-------

reinterpret_cast:
0xbfa8f93d
0xbfa8f93d
Wrong!

C-style cast:
0xbfa8f93d
0xbfa8f93e
Right.


---------
downcasts
---------

reinterpret_cast:
0xbfa8f93e
0xbfa8f93e
Wrong!

C-style cast:
0xbfa8f93e
0xbfa8f93d
Right.