LCOV - code coverage report
Current view: top level - unit_tests/tests - test_cpp_memory_layout.cpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 35 39 89.7 %
Date: 2024-04-22 23:59:02 Functions: 16 18 88.9 %

          Line data    Source code
       1             : /*
       2             :  * test_cpp_memory_layout.cpp
       3             :  *
       4             :  * Jun 15, 2019
       5             :  * @author Andrey Belomutskiy, (c) 2012-2020
       6             :  */
       7             : 
       8             : #include "pch.h"
       9             : 
      10             : // in C++ struct is pretty much a class just fields are public by default
      11             : struct TestParent {
      12             :         int field0 = 540;
      13             :         float field1 = 333.33;
      14             : };
      15             : 
      16             : class TestPlainChild: public TestParent {
      17             : public:
      18             :         float getSum();
      19             : };
      20             : 
      21             : class TestPlainChildExtraFields: public TestParent {
      22             : public:
      23             :         float field3 = 35555;
      24             :         float field4 = 45555;
      25             : };
      26             : 
      27             : 
      28           0 : float TestPlainChild::getSum() {
      29           0 :         return field0 + field1;
      30             : }
      31             : 
      32             : class TestChildWithVirtual: public TestParent {
      33             : public:
      34           0 :         virtual float getSumVirtual() {
      35           0 :                 return field0 + field1;
      36             :         }
      37             : };
      38             : 
      39             : 
      40           4 : TEST(CppMemoryLayout, PlainStruct) {
      41           1 :         TestPlainChild c;
      42             :         // validate field initializers just for fun
      43           1 :         ASSERT_EQ(540, c.field0);
      44           1 :         ASSERT_NEAR(333.33, c.field1, EPS4D);
      45             : 
      46           1 :         ASSERT_EQ(sizeof(c), sizeof(TestParent));
      47             : 
      48           1 :         int destimationInt = 1;
      49             :         // no virtual table since nothing virtual on TestPlainChild
      50           1 :         memcpy(&destimationInt, &c, 4);
      51           1 :         ASSERT_EQ(540, destimationInt);
      52             : 
      53           1 :         ASSERT_EQ((uintptr_t)&c.field0, (uintptr_t)&c);
      54             : }
      55             : 
      56             : static int valueWePointAt;
      57             : 
      58           4 : TEST(CppMemoryLayout, VirtualStruct) {
      59           1 :         TestChildWithVirtual c;
      60             : 
      61             :         // '4' in case of 32 bit target
      62             :         // '8' in case of 64 bit target
      63           1 :         int MAGIC_VTABLE_SIZE = sizeof(void*);
      64             : 
      65             :         // validate field initializers just for fun
      66           1 :         ASSERT_EQ(540, c.field0);
      67           1 :         ASSERT_NEAR(333.33, c.field1, EPS4D);
      68             : 
      69           1 :         ASSERT_EQ(sizeof(c), sizeof(TestParent) + MAGIC_VTABLE_SIZE);
      70             : 
      71             : 
      72           1 :         int destimationInt = 1;
      73           1 :         memcpy(&destimationInt, &c, 4);
      74           1 :         ASSERT_NE(540, destimationInt);
      75             : 
      76             :         // static_cast is smart to skip the vtable, we like static_cast
      77           1 :         TestParent *parent = static_cast<TestParent*>(&c);
      78           1 :         ASSERT_EQ((uintptr_t)&c.field0, (uintptr_t)parent);
      79             : 
      80           1 :         ASSERT_EQ(MAGIC_VTABLE_SIZE, (uintptr_t)&c.field0 - (uintptr_t)&c);
      81             : 
      82             : 
      83             : }
      84             : 
      85           4 : TEST(CppMemoryLayout, PlainExtraFieldsStruct) {
      86           1 :         TestPlainChildExtraFields c;
      87             : 
      88           1 :         ASSERT_EQ(sizeof(c), sizeof(TestParent) + 8);
      89             : 
      90           1 :         int destimationInt = 1;
      91             :         // parent fields go first
      92           1 :         memcpy(&destimationInt, &c, 4);
      93           1 :         ASSERT_EQ(540, destimationInt);
      94           1 :         ASSERT_EQ(0, (uintptr_t)&c.field0 - (uintptr_t)&c);
      95             : }
      96             : 
      97           4 : TEST(CppMemoryLayout, structSize) {
      98           1 :         ASSERT_EQ(1, sizeof(adc_channel_e)) << "adc_channel_e enum size";
      99           1 :         ASSERT_EQ(1, sizeof(pin_input_mode_e)) << "pin_input_mode_e enum size";
     100           1 :         ASSERT_EQ(1, sizeof(pin_output_mode_e)) << "pin_output_mode_e enum size";
     101           1 :         ASSERT_EQ(2, sizeof(brain_pin_e)) << "brain_pin_e enum size";
     102           1 :         ASSERT_EQ(12, sizeof(air_pressure_sensor_config_s));
     103           1 :         ASSERT_EQ(TOTAL_CONFIG_SIZE, sizeof(persistent_config_s));
     104             : }

Generated by: LCOV version 1.14