60KB diff between class and equivalent struct? Huh?

I just began to port some code over from the Uno class devices to the Due.

I was surprised at how much larger even a small program compiled to, and so far the main culprit seems to be a 60K jump when instantiating even a minimal class.

Oddly, doing the same with a struct with the same functionality did not have such a big jump! For example:

// change between 1 and 0, compile for Due
#if 0
class test {
public:
#else
struct test {
#endif

  test() { i = 1; }
  void incr() { i++; }
  int i;
};

void setup() {
  test *tp = new test();
  tp->incr();
}

void loop() {
}

Both the struct and the class have publicly available a member variable, a constructor and a function. But using the class keyword jumps memory usage from 12K to 72K.

What's up with that? Can I really save 60K by using structs rather than classes (with appropriate use of public: and private: to match class dynamics)? That makes no sense.

(Just to be clear: that's a C++ type struct obviously - which I understand to be just like a class except defaulting to public: visibility; with a member method and a constructor, it's not a simple C type struct so that doesn't explain the difference).

There’s something you’re not showing. The difference between a struct and a class, both containing essentially the same data elements, will be nearly zero. A class is, after all, simply an extension of a struct. Provide a complete, compilable example…

Regards,
Ray L.

First -Thanks for responding; the code above WAS the complete compilable example in full. I distilled it to a minimal sketch so people could easily reproduce it.

However—

The above problem was with 1.5.7 (I’m sure one could reproduce it there)
The 60K penalty seems to be gone with 1.6.4

There is still an anomaly in that with the struct version (but not the class version), the compiler issues a warning about unresolved references to setup() and loop() in main(). But it does not error out when compiling for Due, just warns.

(When compiling for Uno, the class version is OK but the struct version errors out! Any ideas?)

Add “#include <Arduino.h>” at the top of the file. I get 1282 bytes program size for either class or struct.

Regards,
Ray L.

Ray, are you sure you are compiling for the Due? You don't even have to have one, just select it as a target when compiling. Quite a bit bigger, no?

This came up in beginning to port code from the Uno to the Due, and noticing a huge code expansion, and seeking some explanation. This test snippet went from 1K on the Uno to 12-72K on the Due (depending on whether one used a struct or a class).

That was probably a bug in the compiler or its usage in 1.5.7, since fixed.

Nevertheless, the test snippet is 10x larger on the Due even with 1.6.4, probably because some weighty library which was not sufficiently subdivided to pull in only the few functions needed.

Thanks for trying it out.

RayLivingston:
Add “#include <Arduino.h>” at the top of the file.

Just by the way, both versions of the snippet compile for the Due without that line, and the class version compiles without it for the Uno. But the struct version fails to compile for the Uno without that line!

Since I’ve been using classes, my code has been working without the include so I have slipped into omitting the include line, without error. I thought the IDE was now inserting it automatically as it massages the text, which is probably true sometimes. Thanks for the reminder that IN SOME CASES (depending on your code and the target) you still need to include it. Quirky, eh? Safest to always do so.

AND this had nothing to do with the original issue of 72K vs 12K vs 1K of code size.

I would imagine that the difference is that the 1.5.x versions of the IDE would include a giant chunk of standard library when you used new. Presumably the compiler was optimizing the struct version to not actually use new and so it didn't get the penalty. In the 1.6.x branch they fixed this problem by creating small implementations of new and delete. Thus 1.6.x branch compiled code tends to end up something like 30k smaller than 1.5.x compiled code.