Podivné chování jazyka C++ – C / C++ – Fórum – Programujte.com
 x   TIP: Přetáhni ikonu na hlavní panel pro připnutí webu
Reklama
Reklama

Podivné chování jazyka C++ – C / C++ – Fórum – Programujte.comPodivné chování jazyka C++ – C / C++ – Fórum – Programujte.com

 

Hledá se programátor! Plat 1 800 € + bonusy (firma Boxmol.com)
NeprijemnePrekvapeny
~ Anonymní uživatel
2 příspěvky
26. 4. 2013   #1
-
0
-

Ahoj,

narazil jsem na podivné chování jazyka C++. Mám dva soubory proc1.cpp a proc2.cpp. V obouch dvou je třída stejného názvu IMP s implementací něčeho, která je zvenčí nepřístupná, proc1.cpp a proc2.cpp vzájemně nevědí co je v tom druhém. Ven jsou vytaženy jen funkce proc1() a proc2() které používají ty třídy IMP s implementací. Potíž je že z proc2 se volá blbý konstruktor, měl by se volat kontruktor IMP z proc2, ale volá se konstruktor IMP z proc1. Samozřejmě když se každá ta třída jmenuje jinak, tak problém zmizí. Není mi ale jasné proč když se jmenujou stejně to takhle blbne, když jsou ty třídy kompletně oddělený. Nejdřív jsem z toho vinil překladač (Visual Studio 6), ale v GCC to dělá taky. Dovede to někdo vysvětlit?

// proc1.cpp :

#include <stdio.h>

class IMP {
public:
  IMP() { printf("Tady konstruktor z proc1.cpp\n"); }
  int a;
  int b;  
}; 

void proc1()  
{                                                                             
  printf("Volam konstruktor z proc1.cpp\n");
  IMP* imp = new IMP;
  delete imp;                                                     
} 

// proc2.cpp :

#include <stdio.h>

class IMP {
public:
  IMP() { printf("Tady konstruktor z proc2.cpp\n"); }
  int a;
}; 

void proc2()  
{                                                                             
  printf("Volam konstruktor z proc2.cpp\n");
  IMP* imp = new IMP;
  delete imp;                                                     
} 

// main.cpp :

#include <stdio.h>

extern void proc1();  
extern void proc2();  

int main(int argc, char* argv[])
{
  proc1();
  proc2();
  getchar();
  return 0;
}

A po spuštění to vypíše:

Volam konstruktor z proc1.cpp
Tady konstruktor z proc1.cpp
Volam konstruktor z proc2.cpp
Tady konstruktor z proc1.cpp

?

Nahlásit jako SPAM
IP: 193.138.153.–
Reklama
Reklama
KIIV+42
God of flame
26. 4. 2013   #2
-
0
-

a jak to kompilujes?

Nahlásit jako SPAM
IP: 62.168.56.–
Program vždy dělá to co naprogramujete, ne to co chcete...
NeprijemnePrekvapeny
~ Anonymní uživatel
2 příspěvky
26. 4. 2013   #3
-
0
-

Jo, je to tak, dík za trknutí. Má to co dělat s kompilací, respektive že překladač neposkytne linkeru informace pro správný sestavení.

Záleží na pořadí v jakém ty překladové jednotky linker sestavuje. Když je to v pořadí proc1.cpp proc2.cpp, tak to blbne jak jsem popsal. Když v pořadí obráceném tak to blbne obráceně. :-)

Tedy někde uvnitř mezi překladačem a linkerem ty třídy mají stejný interní název i když jsou v různých překladových jednotkách. A když mají stejný název tak pak linker vidí jen první z ních. Kterou z nich závisí na pořadí sestavování.

Tyhle věci má zdá-se C++ pořádně nedořešený, nebyl by přece vůbec problém aby když je to v různejch překladovejch jednotkách těm třídám překladač automaticky přidělil různý interní názvy aby to linker sestavil správně.

Řešení je umístit ty stejně pojmenovaný třídy do anonymních namespace.

namespace {

class IMP {
// ...
};

};

Pak už to překladač konečně pochopí a chodí to správně. Hurá :-)

Nahlásit jako SPAM
IP: 193.138.153.–
hlucheucho+10
Posthunter
26. 4. 2013   #4
-
0
-

a co použít pro každou jednotku namespace?

hu

Nahlásit jako SPAM
IP: 188.95.60.–
Zjistit počet nových příspěvků

Přidej příspěvek

Toto téma je starší jak čtvrt roku – přidej svůj příspěvek jen tehdy, máš-li k tématu opravdu co říct!

Ano, opravdu chci reagovat → zobrazí formulář pro přidání příspěvku

×Vložení zdrojáku

×Vložení obrázku

Vložit URL obrázku Vybrat obrázek na disku
Vlož URL adresu obrázku:
Klikni a vyber obrázek z počítače:

×Vložení videa

Aktuálně jsou podporována videa ze serverů YouTube, Vimeo a Dailymotion.
×
 
Podporujeme Gravatara.
Zadej URL adresu Avatara (40 x 40 px) nebo emailovou adresu pro použití Gravatara.
Email nikam neukládáme, po získání Gravatara je zahozen.
-
Pravidla pro psaní příspěvků, používej diakritiku. ENTER pro nový odstavec, SHIFT + ENTER pro nový řádek.
Sledovat nové příspěvky (pouze pro přihlášené)
Sleduj vlákno a v případě přidání nového příspěvku o tom budeš vědět mezi prvními.
Reaguješ na příspěvek:

Uživatelé prohlížející si toto vlákno

Uživatelé on-line: 0 registrovaných, 76 hostů

Moderátoři diskuze

 

Hostujeme u Českého hostingu       ISSN 1801-1586       ⇡ Nahoru Webtea.cz logo © 20032016 Programujte.com
Zasadilo a pěstuje Webtea.cz, šéfredaktor Lukáš Churý