-1

My question is more like: Why the compiler "thinks" that a "PROGMEM variable" is the same as a "plain Variable"? is it because PROGMEM-keyword is "just" a macro and nothing more? or is it for some other reason too? and is there any workaround..?

ISSUE demonstration:

Lets consider the below example:

class object {
public:
  object(int* variable);
  object(int* variable PROGMEM);
};

it throws error: 'object::object(int*)' cannot be overloaded as if it is the same.

sketch_jul31a:4:3: error: 'object::object(int*)' cannot be overloaded

   object(int* variable PROGMEM)

   ^~~~~~

sketch_jul31a:3:3: error: with 'object::object(int*)'

   object(int* variable)

   ^~~~~~

exit status 1
'object::object(int*)' cannot be overloaded

Outro:

I came across this issue a while ago when i was developing a library, I've asked about it on the arduino-forum but i had not any answer and so i've thought after a long period to ask about it once again, here.

Giorgos Xou
  • 1,461
  • 1
  • 13
  • 32
  • 1
    That annotation doesn't make sense for a function parameter that's a plain value. Overloading on pointer to progmem versus pointer to data memory would make some sense, but that would have to be part of the type of the pointer - can't remember if there's an annotation for that. – Mat Jul 31 '21 at 17:32
  • 2
    PROGMEM is information for the linker where to store the variable. it has nothing to do with the variable type. – Juraj Jul 31 '21 at 17:36
  • @Mat my fault on this, i forgot the * before posting it lol – Giorgos Xou Jul 31 '21 at 17:42
  • @Juraj that's quite sad.. and it's what i was expecting as an answer actually... – Giorgos Xou Jul 31 '21 at 17:54
  • **I was hoping for a workaround though...** – Giorgos Xou Jul 31 '21 at 18:06
  • there it is in the second answer – Juraj Jul 31 '21 at 19:20

2 Answers2

3

You can't expect the compiler to treat linker sections as type qualifiers, but you can define an overload for a const int*, which is pretty close to the semantics of PROGMEM (a ROM location).

I wonder what you plan on doing with a const int* though. All you will ever be able to do is read it, so it's basically equivalent to a plain constant int value, with the added cost of two bytes of ROM.

kuroi neko
  • 8,479
  • 1
  • 19
  • 43
  • **That's a great one!** it makes sense for something like ```const int* variable PROGMEM``` since PROGMEM, is constant anyways. That was just a "silly" example of mine, in my case [i had to store a banch of weights and biases](https://github.com/GiorgosXou/NeuralNetworks/blob/e3f0db1d173d2dd03e32aebbaf9d14c71941bf99/src/NeuralNetwork.h#L350) *(for readonly purposes if PROGMEM)*, but at the end i got away with MACROS.. – Giorgos Xou Jul 31 '21 at 19:31
  • I see. Glad to have been of help :) – kuroi neko Jul 31 '21 at 22:01
0

__attribute__((progmem)) is a compiler feature, not a C++ language feature, so it does not participate in the overload resolution. The both object(int variable); and object(int variable PROGMEM); looks like the double declaration of object(int variable); in terms of C++.

273K
  • 29,503
  • 10
  • 41
  • 64