static const char c[] __PROGMEM

In some libs, I see such constructions:

static const char c[] __PROGMEM = {...}

I do not really see what is the point of static specifier.
Can anyone elaborate?

As well, due different versions of arduino, usage and place of specifier __PROGMEM changes.
What is current "proper" way with 1.6.12(13) ?

If it's in a library it's probably in a class? If so, just Google "static variable class". In short, it's the same for all instances.

And as far as I know this is still the correct way.

Unfortunately, static has several different meanings, depending on where it appears.

In this case, the static keyword is used to make sure that no other files can see the variable name "c". It allows you to use a simple name and only worry about name collisions within that file. Without the static keyword, the name "c" for a const char array could not appear in any other file. The linker would complain about "multiple definitions". In general, it should be used for any file-scope variable that is not intended to be accessible outside the file.

When used inside a class declaration (e.g., the H file), the static keyword on a data member means that all instances of that class share that "static" member. Without the static keyword, each instance has its own copy of that member.

Cheers,
/dev

arduino_314:
In some libs, I see such constructions:

static const char c[] __PROGMEM = {...}

I do not really see what is the point of static specifier.
Can anyone elaborate?

As well, due different versions of arduino, usage and place of specifier __PROGMEM changes.
What is current "proper" way with 1.6.12(13) ?

Don't know where you are getting the underscores from, but the correct form is:

[b]static const var_type var_name[] PROGMEM = {
    element1, element2, element3, etc...
};[/b]

-- or --

[b]static const ver_type var_name PROGMEM = value;[/b]

The "static" keyword simply keeps the variable NAME from polluting other namespaces.

Thank you all.

As a senior desktop programmer, of course I understand the meaning and usage of static, but not in this context with PROGMEM (allowed to be used by AVR-GCC , for modified Harvard architecture, MCU specific, AVR in this case). It is really weird construction for me.

This can be found in NeoGPS lib, the author is the member /dev, if I have calculated 1+1 correctly. :slight_smile:

In some libs, I see...

Heh, heh, I knew what you meant by "some libs"....

I understand... static, but not in this context with PROGMEM

To be clear, the static keyword is independent from PROGMEM. static does what it has always done: limit the identifier (i.e., "name") scope to that file, regardless of where it's stored (RAM or FLASH).

The __PROGMEM form is from Cosa, an excellent Object-Oriented alternative to the Arduino framework. I was trying to maintain the same code base on both systems. The author of Cosa (properly) used the double underscore to indicate that this "keyword" (actually a #define) is compiler-specific. Experienced programmers would immediately recognize it as such.

It also helps isolate Cosa from changes to this keyword by the Arduino gods.

Cheers,
/dev,
who was nervously waiting for the finger of blame to be pointed. :wink:

/dev:
Heh, heh, I knew what you meant by "some libs"....

I knew that you will not resist to reply on the topic... :wink:

/dev:
Cheers,
/dev,
who was nervously waiting for the finger of blame to be pointed. :wink:

I had no plans to do that, but Krupski was interested... But, I do not ran away from guilty for what I did...:wink:

Aside a joke, thank you very much for your time to explain this weird construction for me!

Krupski:
Don't know where you are getting the underscores from, but the correct form is:

[b]static const var_type var_name[] PROGMEM = {

element1, element2, element3, etc...
};[/b]




-- or --



static const ver_type var_name PROGMEM = value;




The "static" keyword simply keeps the variable NAME from polluting other namespaces.

Although this is not related to the "static" issue, I have also seen (and now used) another construct for a PROGMEM definition:

const char MAIN_page[] PROGMEM = R"=====(
       you can put anything you like here and it is not interpreted ' " }  //   /*
       )   -  ]    
)=====";

Interestingly, on the ESP8266 at least , you can then go on to do something like this without using pgm_read_word etc. :

String s = MAIN_page ;
Serial.print( s ) ;
// etc. etc.