Ģ ([info]smejmoon) rakstīja [info]koderi kopienā,
@ 2008-07-24 08:04:00

Previous Entry  Add to memories!  Tell a Friend!  Next Entry
extern "C"
kāda ir atšķirība starp
extern "C" T v;
un
extern T v;

iekš to gcc un msvc?


(Ierakstīt jaunu komentāru)


[info]watt
2008-07-24 20:41 (saite)
es nesaprotu īsti tavu jautājumu - vai tas ir par C un C++ linkošanu - valodas līmenī?
vai tas ir par gcc ? (precīzāk gan būtu par g++ jautāt)
vai tas ir par microsoft c++ kompilatoru ? un kuru versiju, tad?

(Atbildēt uz šo) (Diskusija)


[info]smejmoon
2008-07-24 21:15 (saite)
c++ faili.

Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 15.00.21022.08 for 80x86
gcc 4.0.1


tas pats kods ar gcc nelinkojas bez "C"

(Atbildēt uz šo) (Iepriekšējais) (Diskusija)


[info]watt
2008-07-24 21:41 (saite)
http://en.wikipedia.org/wiki/Name_mangling
http://en.wikipedia.org/wiki/Compatibility_of_C_and_C%2B%2B#Linking_C_and_C.2B.2B_code

(Atbildēt uz šo) (Iepriekšējais) (Diskusija)


[info]smejmoon
2008-07-24 22:54 (saite)
kapēc tas ir svarīgi, ja visi .o faili tiek kompilēti ar to pašu kompilatoru?

(Atbildēt uz šo) (Iepriekšējais) (Diskusija)


[info]bubu
2008-07-25 02:11 (saite)
.o failus īstenībā neviens jau nekompilē... Tos tikai linko kopā vai arhivē statiskā libā.

Bet kā jau teicu - tas ir tāpēc, ka extern "C" atslēdz vārda manglošanu. Tāpēc extern X y; nav tas pats, kas extern "C" X y; Linkeris šos mainīgos redz kā divus dažādus (tb ar diviem dažādiem nosaukumiem).
C:\test>type a.cpp
#include <string>

// deklaraacijas

extern "C" std::string foo;
extern std::string bar;

// definiiicjas

std::string foo;
std::string bar;

C:\test>cl /c /EHsc a.cpp
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 15.00.21022.08 for 80x86
Copyright (C) Microsoft Corporation.  All rights reserved.

a.cpp

C:\test>objdump --syms a.obj | grep foo
[149](sec 50)(fl 0x00)(ty  20)(scl   3) (nx 0) 0x00000000 ??__Efoo@@YAXXZ
[197](sec 65)(fl 0x00)(ty  20)(scl   3) (nx 0) 0x00000000 ??__Ffoo@@YAXXZ
[207](sec 68)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x00000000 _foo
[210](sec 69)(fl 0x00)(ty   0)(scl   3) (nx 0) 0x00000000 _foo$initializer$

C:\test>objdump --syms a.obj | grep bar
[194](sec 64)(fl 0x00)(ty  20)(scl   3) (nx 0) 0x00000000 ??__Ebar@@YAXXZ
[203](sec 67)(fl 0x00)(ty  20)(scl   3) (nx 0) 0x00000000 ??__Fbar@@YAXXZ
[206](sec 68)(fl 0x00)(ty   0)(scl   2) (nx 0) 0x0000001c ?bar@@3V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@A
[211](sec 69)(fl 0x00)(ty   0)(scl   3) (nx 0) 0x00000004 _bar$initializer$

C:\test>
bar, kā redzams, nepavisam nav _bar.

Ar GCC (4.2.1 win32 gan arī 4.3.1 x84-64) man šito joku gan neizdevās atkārtot. Tur vienmēr foo ir _foo un bar ir _bar. Tb var rakstīt vai var nerakstīt to extern "C" - GCC kompilētājam pofig (vismaz pie mainīgo nosaukumiem). Pie funkcijām vai metodēm gan uzreiz aiziet manglošanās.

(Atbildēt uz šo) (Iepriekšējais) (Diskusija)


[info]smejmoon
2008-07-25 04:08 (saite)
hhmm.. ok. objdump - paldies par rīku:)

(Atbildēt uz šo) (Iepriekšējais)


[info]bubu
2008-07-24 21:21 (saite)
Šķiet, ka atšķirība ir tikai C++ valodā. C valodā extern "C" nemaz nevar rakstīt.

Cik zinu extern "C" atslēdz name mangling eksportētajam simbolam. Tik dīvaini, ka mainīgā vārds varētu tikt "manglots". Funkcijas - jā, tām vārds manglojas.

Ja nu vienīgi T ir kautkāda struktūra, tad gan iespējams MSVC samanglo vārdu.
Tb extern "C" T v; nodeklarēts mainīgais vienā failā nokompilēsies ar vārdu _v, taču, ja otrā failā būs tikai T v; (bez extern "C"), tad nekas nesalinkosies kopā.

(Atbildēt uz šo) (Diskusija)


[info]smejmoon
2008-07-24 21:31 (saite)
Paldies. Tā varētu būt. T ir Template, tā ka tur manglošana drošivien notiek uz nebēdu;

(Atbildēt uz šo) (Iepriekšējais)


[info]jf_
2008-07-25 07:29 (saite)
Kā, kāda atšķirība? Pirmajā variantā tur ir "C", otrajā nav :D

(Atbildēt uz šo)


Neesi iežurnalējies. Iežurnalēties?