LPCxpresso: Potize s optimalizaci

Milan B. milan na bastl.sk
Středa Červenec 27 22:04:53 CEST 2016


On 27. 7. 2016 14:29, Jan Waclawek wrote:
>> su ludia ktorych chyta
>> hroza ked v .h subore vidia deklaraciu niecoho co alokuje pamat
> Deklaracia niecoho co alokuje pamat sa nazyva definicia (C99 6.7.#5).
> Pouzivanie tohoto pojmu zjednodusuje a zjednoznacnuje veci.
>
> Je to dobry zvyk, lebo tak nealokujes tu pamat omylom viackrat. Nejde o tu
> pamat ale o vzajomnu viditelnost tych viackrat alokovanych veci z roznych
> modulov.

Tú pamät nenaalokujem viackrát ani keby som ako veľmi chcel a vždy 
uvidím tú istú premennú.

Je to tak trochu zrada - viacnásobná definícia globálnej premennej v 
rôznych súboroch ma úplne rovnaký efekt či ju striktne v jednom súbore 
definujem (bez extern)  a v ostatných deklarujem (s extern) - bude 
alokovaná len raz. Podmienkou je, že musí byť definovaná aspoň raz.

V nasledujúcom príklade by človek intuitívne očakával, že linker vyhlási 
chybu na tému duplicitnej premennej... no nestane sa tak, všetky 
definície sa považujú za definície tejže premennej. (technicky sa 
globálne premenné  umiestňujú do sekcie COMMON (ďakujeme, FORTRAN) a 
linker s nimi príslušne naloží).

V norme sa tiež brble niečo ako "If the declaration of an identifier for 
an object has file scope and no storage-class specifier, its linkage is 
external." a krátko predtým "each declaration of a particular identifier 
with external linkage denotes the same object or function"

To samozrejme prináša iné nepríjemnosti. Ak omylom vo väčšom projekte 
zadefinujem dve rôzne (významovo) premenné náhodou pod tým istým menom, 
o probléme sa nedozviem a nebudem sa stačiť diviť, prečo majú premenné 
podivné hodnoty.

==== a1.c
int premenna;

void setp1 (int v)
{
         premenna = v;
}

==== a2.c
int premenna;

void setp2 (int v)
{
         premenna = v;
}

==== a0.c
#include <stdio.h>

extern int premenna;

extern void setp1 (int v);
extern void setp2 (int v);

int main()
{
         premenna = 1;
         printf ("%d\n", premenna);
         setp1 (10);
         printf ("%d\n", premenna);
         setp2 (20);
         printf ("%d\n", premenna);

         exit(0);
}

$ gcc -Wall -o a a0.c a1.c a2.c
$ ./a
1
10
20

-m-



> Takze spravne:
> - globalna premenna ma byt *definovana* (t.j. bez extern) len v jedinom .c
> subore
>
> - globalna premenna ma byt *deklarovana* (t.j. nie definovana, t.j. *s*
> extern) v nejakom .h (typicky s rovnakym menom ako je .c kde je definovana)
>
> - tento .h ma byt #includnuty do vsetkych suborov kde sa tato globalna
> premenna pouzije, vratane toho, kde bola *definovana*
>
>
> Toto je stabna kultura, ktora nie je prekladacom natvrdo vyzadovana, ktora
> ale ak sa rigorozne dodrziava, tak svet je jednoduchsi a krajsi.
>
> -----------
>
> Tak este raz, a pomaly:
>
> ---
> a.h:
> #include <stdint.h>
> extern volatile uint8_t flag;
>
> ---
> a.c:
>
> #include "a.h"
>
> volatile uint8_t flag;
>
> void callback(void) { // resp. akekolvek ine veci
>    flag = 1;
> }
>
> ----
> main.c:
>
> #include "a.h"
>
> int main(void) {
>    // inicializacia hardwaru
>    // inicializacia toho callbacku
>    while(1) {
>      if (flag == 1) {
>        printf("Moohoo\n"); // alebo zablikanie LED alebo ekvivalent
>        flag = 0;
>      }
>    }
> }
>
>
>
> ---
>
> Skuste urobit MINIMALISTICKY projekt v ktorom nie je nic zbytocne okrem
> tohoto. Toto musi fungovat
>
> wek
>
>
> _______________________________________________
> HW-list mailing list  -  sponsored by www.HW.cz
> Hw-list na list.hw.cz
> http://list.hw.cz/mailman/listinfo/hw-list



------------- další část ---------------
A non-text attachment was scrubbed...
Name: smime.p7s
Type: application/pkcs7-signature
Size: 3810 bytes
Desc: S/MIME Cryptographic Signature
URL: <http://list.hw.cz/pipermail/hw-list/attachments/20160727/660da25d/attachment.bin>


Další informace o konferenci Hw-list