1

I am having trouble understanding a line of code. I see that an array is initialized as follows:

static const uint SmartBatteryWattHoursTable[1 << 4] = {
  0,  14,  27,  41,  54,  68,  86, 104,
120, 150, 180, 210, 240, 270, 300, 330};

However I can't tell what the following code means:

int x  = sizeof(SmartBatteryWattHoursTable) / sizeof(*SmartBatteryWattHoursTable));

I understand that the numerator will evaluate to 16 * 4 = 64. But what does the denominator evaluate to?

  • Is this code trying to be difficult on purpose? `1 << 4` is an obtuse way to express 16. I think the intention of the second part is to de-reference a decayed array pointer to get the size of a single element, or `sizeof(uint)`. – tadman Jul 15 '20 at 02:27
  • Tip: In C++ try and use `std::vector` because then the length is `len()`. No guessing. – tadman Jul 15 '20 at 02:27
  • you should ask your question with tag C, you will get more friendly answers. Good luck rookie! – Antonin GAVREL Jul 15 '20 at 02:28
  • 1
    https://stackoverflow.com/questions/37538/how-do-i-determine-the-size-of-my-array-in-c – Retired Ninja Jul 15 '20 at 02:32
  • I guess you never thought of doing `std::cout << sizeof(*SmartBatteryWattHoursTable);` – paddy Jul 15 '20 at 04:23

2 Answers2

7

But what does the denominator evaluate to?

sizeof(*SmartBatteryWattHoursTable) evaluates to the size of the type of the expression *SmartBatteryWattHoursTable. The type of that expression is the same as the element of the array, which is uint.

In other words, sizeof(SmartBatteryWattHoursTable) / sizeof(*SmartBatteryWattHoursTable)) is a way to calculate the size of the array in number of elements (as opposed to the size in number of bytes that the numerator is).

A simpler way to write this is std::size(SmartBatteryWattHoursTable).

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
eerorika
  • 232,697
  • 12
  • 197
  • 326
  • you mean, `*SmartBatteryWattHoursTable == SmartBatteryWattHoursTable[0]`? i.e. `sizeof(int)`? – Shubham Jul 15 '20 at 04:09
  • @Lucas Yup. More on the subject: [What is array to pointer decay?](https://stackoverflow.com/questions/1461432/what-is-array-to-pointer-decay) One big take away is arrays are NOT pointers, but can be viewed as pointers. – user4581301 Jul 15 '20 at 04:13
  • @MichaelMcKinney There are the (brand-new) clapping hands under the vote arrows (introduced in the hope to get rid of the "Thank you" comments). ;-) Btw. Please, don't forget to [accept the answer](https://stackoverflow.com/help/someone-answers) which helped you most. – Scheff's Cat Jul 15 '20 at 05:50
4

The code is declaring an array of 16 (1 << 4) uint values.

The statement sizeof(SmartBatteryWattHoursTable) returns the byte size of the entire array, thus sizeof(uint) * 16 = 64 (assuming a 4-byte uint).

An array decays into a pointer to the 1st element, thus *SmartBatteryWattHoursTable is the same as *(&SmartBatteryWattHoursTable[0]). So the statement sizeof(*SmartBatteryWattHoursTable) returns the byte size of the 1st element of the array, ie of a single uint, thus 4.

Thus, x is set to 64 / 4 = 16, ie the number of elements in the array.

This is a very common way to get the element size of a fixed array, prior to the addition of std::size() to the standard C++ library in C++17 (and std::ssize() in C++20).

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770