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