Products > Programming

button_port[start] = 0; has no storage class...... and conflicting data types

<< < (3/3)

Simon:
Of course yes. I had forgotten that putting code in a *.c file is not putting it in main().

Ian.M:
As Siwastaja just pointed out,

--- Code: ---button_port[0] = 0;
--- End code ---
is a statement.  Statements are not allowed outside of functions, (and would be unreachable there anyway), so the compiler attempted to interpret it as a declaration or definition, saw the = and decided it was a definition with initialisation, and complained its invalid, as per the error message.

For your button input driver, if you need to do anything more complex than initialise your arrays with fixed values, you'll need an initialiser function, (which should *NOT* be in your #included header*),  to be called near the beginning of the main() function of your user program.

Its *RARE* for a single header file to be portable between projects - normally the smallest package that is, is a C source file and a header declaring its interfaces.

* see: https://www.gamedev.net/articles/programming/general-and-gameplay-programming/organizing-code-files-in-c-and-c-r1798/

Twoflower:
An alternative to oPossums code:

--- Code: ---#define Bn (3)
uint8_t const button_port[Bn] = { 0 };

--- End code ---
With this code you only need to change the define if the Bh needs to be changed.

Siwastaja:

--- Quote from: Twoflower on October 31, 2019, 09:29:09 am ---An alternative to oPossums code:

--- Code: ---#define Bn (3)
uint8_t const button_port[Bn] = { 0 };

--- End code ---
With this code you only need to change the define if the Bh needs to be changed.

--- End quote ---

Note that this initializes button_port[0] to 0, explicitly, and the rest to 0, implicitly. So you do the same initialization, in two different ways, combined in one command. IMHO, this may be confusing.

If you really want to initialize everything to 0, just omit the initializer; the C standard initializes all global data to zero.

If you wanted to change the table initialization to, say, 1, an inexperienced programmer in hurry might try to change that 0 to 1, assuming the whole table changes in a nice generic way. But it won't - only the first item changes, the array will be 1,0,0. Hence, it's better to leave the explicit initialization out completely, forcing you to think about it if you need to change the initial value (adding a for loop in the beginning of main is a viable generic option, then).

Also, at least some compilers seem to put all explicitly initialized data to the .data section, even if initialized to zero, wasting flash storage. When implicitly initialized to zero, it goes to .bss, without flash storage required.

Twoflower:
Siwastaja is right, the explanations in the Web are not pointing this out and I fell for it. It's get more clear if you do something like uint8_t const button_port[Bn] = { 2 }; and the resulting array is 2, 0, 0.

Depending on the compiler (gcc and clang seem to support this) a construct using designators to specify an area can be used:

--- Code: ---#define Bn (3)
uint8_t const button_port[Bn] = { [0 ... Bn-1] = 2};

--- End code ---
This will initialize the complete array to 2.

But I would not use that as this seems an extension of some compilers and is, to my understanding, not covered by the standard.

Navigation

[0] Message Index

[*] Previous page

There was an error while thanking
Thanking...
Go to full version