Include .c souboru se nepřeloží

Manheim

Include .c souboru se nepřeloží
« kdy: 24. 08. 2017, 20:44:23 »
Čau, nechci spamovat v sekci vývoj, ale mam problém s includem
když napíšu funkci jejíž prototyp dám do .h souboru(# include "prototyp.h"),  a pak napíšu vlastní funkci v .c (soucet.c) souboru tak se mi program bez problému přeloží, ale jakmile udělám toto: #include "soucet.c" tak se program neprovede. jde o to, že já jsem navyklý používat .h souboru, ale tam kde dělám(francouzsko - tuniská firma) includují .c nebo .cpp soubory. je to pro mne více méně novota...

používám linux a gcc, v práci je to pod WIN a postaveno na C++ Builder od Borlandu
« Poslední změna: 28. 08. 2017, 10:15:39 od Petr Krčmář »


Re:Include
« Odpověď #1 kdy: 24. 08. 2017, 21:13:21 »
....
?
A ten .c soubor (#include "soucet.c" ) includují kam?

V hlavičkovém souboru jsou deklarace, proto se mohou includovat do více zdrojových souborů, kde jsou pak definice (tedy právě jedna napříč všemi zdrojáky), velice zjednodušeně.

Othelo

Re:Include
« Odpověď #2 kdy: 24. 08. 2017, 21:18:02 »
Těžko říct, už jsem nějakou dobu neprogramoval a hlavně nevidím, jak je to přesně vložené ani vypsané chyby, ale je někde vložený i ten *.h soubor? Kdysi jsem měl problémy s programem, ve kterém jsem *.h soubory vkládal do *.c souborů, které jsem poté vkládal do hlavního programu a ten *.h soubor se nevložil/jsem jej vložil špatně, už nevím. Každopádně, pokud se to překládá, napíše to chybové hlášky. Asi by bylo dobré tady dát nějaký jednoduchý program s umístěním #include a výpis chybových hlášek, ať je vidět, co se vlastně nevkládá.

Manheim

Re:Include
« Odpověď #3 kdy: 24. 08. 2017, 21:26:40 »
Díky za response. Jde o to, že já to píšu opravdu jinak, prostě prototyp do .h souboru a vlastní funkci do .c souboru. jenže tady kde dělám do toho píšou francouzi, tunis a ještě další dva teamy a každý to píše jinak. Což pak dělá tyhle problémy.
Já si sestavil svuj vlastní program, ten je následující.

.h soubor:

Kód: [Vybrat]
#ifndef FUNKCE_H
#define FUNKCE_H


int soucet(int a, int b);


#endif

.c soubor, který následně includuji do main. V tomto .c souboru mam includovany i .h soubor

Kód: [Vybrat]
#include <stdio.h>
#include <stdlib.h>
#include "funkce.h"

int soucet(int a, int b);

int soucet(int a, int b) {
   
  int sum;

sum = a + b; 
   
return sum;

};

a nakonec main:

Kód: [Vybrat]
#include <stdio.h>
#include <stdlib.h>

#include "soucet.c"

int main(int argc, char** argv) {
   
    printf("%i\n", soucet(2, 2));
   
    return 0;
}

hlášky, co i vypíše gcc do terminálu:

/tmp/ccdth71N.o: In function `soucet':
soucet.c:(.text+0x0): multiple definition of `soucet'
/tmp/ccztTNY3.o:main.c:(.text+0x0): first defined here
collect2: error: ld returned 1 exit status

Jak říkám, já jsem zvyklý psát knihovny jinak, takže v tom teď docela plavu v práci...

Manheim

Re:Include
« Odpověď #4 kdy: 24. 08. 2017, 21:28:39 »
....
?
A ten .c soubor (#include "soucet.c" ) includují kam?

V hlavičkovém souboru jsou deklarace, proto se mohou includovat do více zdrojových souborů, kde jsou pak definice (tedy právě jedna napříč všemi zdrojáky), velice zjednodušeně.

Do mainu, udělal jsem si na to vlastní testovací prográmek.

Já jsem se s tím setkal dneska poprvé v práci. Čumim na to jako puk, já si knihovny píšu úplně jinak.


Othelo

Re:Include
« Odpověď #5 kdy: 24. 08. 2017, 21:38:15 »
No, zatím jsem to ještě netestoval, ale jako člověk, který se nemůže považovat za dokonalého programátora bych odkázal na stackoverflow. Je to tam popsané vážně mnohem lépe, než bych to kdy já poskládal dohromady, navíc jsem se z toho textu právě naučil něco nového :-)

https://stackoverflow.com/questions/17904643/error-with-multiple-definitions-of-function

Ale ještě si to vyzkouším, taky mě to zajímá. // Aneb já věděl, že jsem ten problém někdy měl! :-)

n

Re:Include
« Odpověď #6 kdy: 24. 08. 2017, 21:43:22 »
No ..to je docela matlanec :)
1) v .c souboru neoptrbeujes explicitne deklarovat fci soucet, kdyz tam includujes .h soubor, ktery ji deklaruje(toto nezpusobuje chybu)

2) nezkousel jsem to, ale chybu ti blije zrejme linker, protoze linkuje jak zkompilovany .c soubor, ktery obsahuje definici fce soucet, tak zkompilovany main soubor, ktery obsahuje opet definici stejne funkce soucet(a to proto ze jsi ji tam includnul). Teoreticky by to asi fungovalo, kdybys kompiloval a linkoval pouze main soubor.
   2a) Nic proti, vim, ze to tak delaji ti lulini kde pracujes, ale tohle je na lamani hnatu. Nejsou to nahodou Indove?

.c soubory se nikdy neincluduji(skoro nikdy.. je to prasarna, nedela se to, pokud se includuji nekde primo definice, tak se pojmenovavaji jinak(.inc, nebo tak)

Predstav si, ze pri  #include se stane to, ze preprocesor vezme soubor, ktery ten include specifikuje a pastne ho misto toho include. Takze obsah .c je v miste include. Ale ty zkompilujes a slinkujes jak .c tak main. A v obou mas definici funkce soucet se stejnou hlavickou a ve stejnem namespacu. Linker pak nevi co s tim, protoze nevi kterou z nich ma pouzivat, nicim se nelisi jejich hlavicka a on je nedokaze rozeznat.

Manheim

Re:Include
« Odpověď #7 kdy: 24. 08. 2017, 21:49:17 »
Díky Othelo za odpověď, stackoverflow čtu pravidelně když něco nevím, ale tohle je podle mne prasárna. Já jsem opravdu naučený dělat to jinak. prostě deklarace funkcí si dát do .h souboru a definice do jednotlivých .c souborů jako moduly.
Ano, jsou to prasata, jsou to francouzi a tunisané hlavně. Každý píšeme něco do projektu, ale je to peklo. Ode dneška do toho koukám jak puk na ledě do branky. Zkusim si ještě ručně zkompilovat jen main a uvdíme co to napíše. Jinak v pondělí budu brečet, aby se mnou šli krok po kroku služebně starší kolegové :D

Neviditelný

Re:Include
« Odpověď #8 kdy: 24. 08. 2017, 21:49:41 »
Díky za response. Jde o to, že já to píšu opravdu jinak, prostě prototyp do .h souboru a vlastní funkci do .c souboru. jenže tady kde dělám do toho píšou francouzi, tunis a ještě další dva teamy a každý to píše jinak. Což pak dělá tyhle problémy.
Já si sestavil svuj vlastní program, ten je následující.

.h soubor:

Kód: [Vybrat]
#ifndef FUNKCE_H
#define FUNKCE_H


int soucet(int a, int b);


#endif

.c soubor, který následně includuji do main. V tomto .c souboru mam includovany i .h soubor

Kód: [Vybrat]
#include <stdio.h>
#include <stdlib.h>
#include "funkce.h"

int soucet(int a, int b);

int soucet(int a, int b) {
   
  int sum;

sum = a + b; 
   
return sum;

};

a nakonec main:

Kód: [Vybrat]
#include <stdio.h>
#include <stdlib.h>

#include "soucet.c"

int main(int argc, char** argv) {
   
    printf("%i\n", soucet(2, 2));
   
    return 0;
}

hlášky, co i vypíše gcc do terminálu:

/tmp/ccdth71N.o: In function `soucet':
soucet.c:(.text+0x0): multiple definition of `soucet'
/tmp/ccztTNY3.o:main.c:(.text+0x0): first defined here
collect2: error: ld returned 1 exit status

Jak říkám, já jsem zvyklý psát knihovny jinak, takže v tom teď docela plavu v práci...

Tak, jak to máš napsané se to nemůže přeložit dobře, protože tam skutečně máš soucet() definován dvakrát. Jednou ve funkce.h a podruhé ve funkce.c. Když z funkce.c odstraníš signaturu funkce soucet() a necháš tam jen tu definici, přeloží a slinkuje se to v pořádku. Pokud budeš includovat .c soubory, měl bys je taky chránit include guardy, jinak dost pravděpodobně na problém vícenásobných definic narazíš zase ale z jiného důvodu. Mimochodem, fakt chceš kopírovat tenhle prasácký styl jen proto, že "se to tam tak dělá"?

Manheim

Re:Include
« Odpověď #9 kdy: 24. 08. 2017, 21:57:29 »
Neviditelný: Já to kopírovat nechci, ale nemám tam žádný prostor pro to, abych to psal tak jak jsem naučený, odhadem to jsou miliony souborů a miliony řádků kódu za ta léta. Jak říkám, píše do toho fůra vývojových teamů z celého světa, je to autodiagnostika. Nehledě na to, že nepoužíváme ani pořádné vývojové prostředí .cpp píšu v notepadu, dynamické knihovny pro WIN se kompilují v IDE, které je postaveno na eclipse a samotná architektura SW je postavena na práci s xml soubory, jež tvoří databázi.Je to taková francouzská diskotéka.

to edit: Opravdu stačilo zkompilovat ručně jen main soubor. Díky za obětavost, já jsem zvyklý psát SW úhledně a modulárně. Tohle je opravdu prasečina pro mne, ale nic s tím nenadělám. Kopírovat to nechci a ani nehodlám, jen se musím přizpůsobit..
ještě jednou díky!

Othelo

Re:Include
« Odpověď #10 kdy: 24. 08. 2017, 21:58:42 »
Díky Othelo za odpověď, stackoverflow čtu pravidelně když něco nevím, ale tohle je podle mne prasárna. Já jsem opravdu naučený dělat to jinak. prostě deklarace funkcí si dát do .h souboru a definice do jednotlivých .c souborů jako moduly.
Ano, jsou to prasata, jsou to francouzi a tunisané hlavně. Každý píšeme něco do projektu, ale je to peklo. Ode dneška do toho koukám jak puk na ledě do branky. Zkusim si ještě ručně zkompilovat jen main a uvdíme co to napíše. Jinak v pondělí budu brečet, aby se mnou šli krok po kroku služebně starší kolegové :D

Taky si nevzpomínám, že bych to dělal takhle mmch. zkusil jsem zkompilovat jak program přepsaný nahoře, tak úpravu podle Stack Overflow příkazem g++ main.c -o soucet a fungují mi bez problému obě. Za mě těžko můžu říct, kde je chyba, protože ji nejsem schopný duplikovat.

n

Re:Include
« Odpověď #11 kdy: 24. 08. 2017, 22:03:42 »
Neviditelný: Já to kopírovat nechci, ale nemám tam žádný prostor pro to, abych to psal tak jak jsem naučený, odhadem to jsou miliony souborů a miliony řádků kódu za ta léta. Jak říkám, píše do toho fůra vývojových teamů z celého světa, je to autodiagnostika. Nehledě na to, že nepoužíváme ani pořádné vývojové prostředí .cpp píšu v notepadu, dynamické knihovny pro WIN se kompilují v IDE, které je postaveno na eclipse a samotná architektura SW je postavena na práci s xml soubory, jež tvoří databázi.Je to taková francouzská diskotéka.

to edit: Opravdu stačilo zkompilovat ručně jen main soubor. Díky za obětavost, já jsem zvyklý psát SW úhledně a modulárně. Tohle je opravdu prasečina pro mne, ale nic s tím nenadělám. Kopírovat to nechci a ani nehodlám, jen se musím přizpůsobit..
ještě jednou díky!

Ja vim, ze se to radi dobre, ale doporucuju ti, zdrhej z tehle firmy... anebo si aspon nech vysvetlit proc to pisou jak prasata.

Lol Phirae

Re:Include
« Odpověď #12 kdy: 24. 08. 2017, 22:05:42 »
odhadem to jsou miliony souborů a miliony řádků kódu za ta léta. Jak říkám, píše do toho fůra vývojových teamů z celého světa, je to autodiagnostika. Nehledě na to, že nepoužíváme ani pořádné vývojové prostředí .cpp píšu v notepadu, dynamické knihovny pro WIN se kompilují v IDE, které je postaveno na eclipse a samotná architektura SW je postavena na práci s xml soubory, jež tvoří databázi.

Sbal kufry a RYCHLE pryč!!!

Jano

Re:Include
« Odpověď #13 kdy: 24. 08. 2017, 22:06:24 »
Deklaracii tam mozes mat kolko chces. Cize "int soucet(int a, int b);" v .c nevadi, akurat je zbytocne.

Tvoj problem je, ze telo sa raz skompiluje v soucet.c a raz v main.c. Riesenim je bud nekompilovat soucet.c (zakazat kompilaciu v C++ Buildri alebo cim to kompilujete) alebo vyhodit #include "soucet.c" z main.c a pridat tam #include "soucet.h".

#includovat .c ma zmysel ten, ze to moze zrychlit kompilaciu velkych projektov (preprocesor cita systemove hlavicky len raz). Vola sa to unity build (https://stackoverflow.com/questions/847974/the-benefits-disadvantages-of-unity-builds).
Ma to zmysel len ked sa kompiluje cely projekt odznova. Pocas vyvoja to moc nema zmysel - kazda zmena sposobi kompletnu rekompilaciu.

#include guards su dobry zvyk (https://en.wikipedia.org/wiki/Include_guard)

Ladislav Michl

Re:Include
« Odpověď #14 kdy: 24. 08. 2017, 22:11:05 »
LTO bez podpory linkeru? ;-)