Gå til innhold

Irriterende og tilsynelatende inkonsisten warning fra GCC ved deklarasjon av struct


Anbefalte innlegg

Hei! Jeg har en struct deklarert i "cell.h" som følger:

struct Cell {
 //Geometry
 double h;   //Cell length [m]
 double a;   //Iris aperture [m]
 double d_n; //Iris thickness / h (normalized)
 double a_n; //Normalized iris aperture: a/lambda
 //Main mode
 double f0;   //Frequency [GHz]
 double psi; //Phase advance [deg]
 double Q;  //Q-factor
 double vg; //Group velocity [%c]
 double rQ; //r/Q [linacOhm / m]
 double Es; //Esurf/Eacc
 double Hs; //Hsurf/Eacc [mA/V]
 double Sc; //Sc/Eacc^2 [mA/V]
 //Wakefield 1st mode
 double f1mn;
 double Q1mn;
 double A1mn;
};

I cell.cpp initialiserer jeg den fra fil slik:

 

Cell Cell_TD_30GHz_v1_fileParse(string& line) {
 istringstream ss(line);

 double a_n;  ss >> a_n;
 double d_n;  ss >> d_n;
 double psi;  ss >> psi;
 double Q;    ss >> Q;
 double vg;   ss >> vg;
 double rQ;   ss >> rQ;
 double Es;   ss >> Es;
 double Hs;   ss >> Hs;
 double f1mn; ss >> f1mn;
 double Q1mn; ss >> Q1mn;
 double A1mn; ss >> A1mn;

 const double lambda = Constants::speed_of_light/29.985e9;
 const double nan = numeric_limits<double>::quiet_NaN();

 Cell ret =  {
   (psi/360.0) * lambda, //h
   a_n * lambda, //a
   d_n, a_n,
   29.985e9, //f0
   psi, Q, vg, rQ,
   Es, Hs,
   nan, //Sc
   f1mn, Q1mn, A1mn
 };
 return ret;
}

og det funker fint. I en annen del av programmet, i konstruktøren til klassen AccelStructure_CLIC502 : public AccelStructure, så initialiserer member-variablene cellFirst...cellLast (protected fields tilhørende moderklassen AccelStructure) som følger:

 

AccelStructure_CLIC502::AccelStructure_CLIC502()
 : AccelStructure(22*10.41467e-3) {

 const double lambda = Constants::speed_of_light/11.9942e9;
 const double h = 10.41467e-3; //[m]

 cellFirst = {h, //h		   [m]
   	   3.97e-3, //a	 [m]
   	   2.08e-3/h,  //d/h
   	   3.97e-3/lambda, //a/lambda
   	   11.993916, //f0  [GHz]
   	   150.0,	 //psi [deg]
   	   6364.8,    //Q
   	   2.056,	 //vg [%c]
   	   10304.92,  //rQ
   	   4.684,	 //Es
   	   2.25,	  //Hs
   	   0.493,	 //Sc
   	   0,0,0};
 cellMid = {h, //h
   	 3.625e-3, //a
   	 1.875e-3/h,  //d/h
   	 3.625e-3/lambda, //a/lambda
   	 11.993975, //f0  [GHz]
   	 150.0,	 //psi [deg]
   	 6370.5,    //Q
   	 1.614,	 //vg  [%c]
   	 11213.4,   //rQ
   	 4.511,	 //Es
   	 2.23,	  //Hs
   	 0.435,	 //Sc
   	 0,0,0};
 cellLast = {h, //h
   	  3.28e-3, //a
   	  1.67e-3/h,  //d/h
   	  3.28e-3/lambda, //a/lambda
   	  11.993984, //f0  [GHz]
   	  150.0,	 //psi [deg]
   	  6383,    //Q
   	  1.234,	 //vg  [%c]
   	  12175.9,   //rQ
   	  4.342,	 //Es
   	  2.22,	  //Hs
   	  0.381,	 //Sc
   	  0,0,0};

}

 

Her gir GCC meg en warning:

structure.cpp: In constructor ‘AccelStructure_CLIC502::AccelStructure_CLIC502()’:
structure.cpp:140: warning: extended initializer lists only available with -std=c++0x or -std=gnu++0x
structure.cpp:140: warning: extended initializer lists only available with -std=c++0x or -std=gnu++0x
structure.cpp:153: warning: extended initializer lists only available with -std=c++0x or -std=gnu++0x
structure.cpp:153: warning: extended initializer lists only available with -std=c++0x or -std=gnu++0x
structure.cpp:166: warning: extended initializer lists only available with -std=c++0x or -std=gnu++0x
structure.cpp:166: warning: extended initializer lists only available with -std=c++0x or -std=gnu++0x

 

Hva er det jeg gjør galt her? Jeg greier ikke se forskjellen... Bruker gcc4.4.6 på Scientific Linux CERN 6.2 (~= RHEL 6.2) dersom det har noe å si.

Lenke til kommentar
Videoannonse
Annonse

Aha, så det var greia!

 

Men hva er riktig måte å gjøre dette på? GCC-versjonen jeg bruker har litt flaky C++11-støtte (f.eks. kan jeg ikke bruke {.h = blabla, ...} ), så vil helst unngå hele greia.

 

Må jeg si noe ala

cellFirst.h = blaba;
cellFirst.a = blbl;
cellFirst.d_n = fdasklø;

osv. ?

Lenke til kommentar

Eller en constructor. Vil antagelig bli (hakket) kjappere og.

 

Men om jeg bruker constructor, vil den da fortsatt være en POD? I andre steder av programmet så driver jeg og trikser med offsetof() for å kunne skrive kode som behandler en hvilken som helst av variablene i struct'en - på mange måter så bruker jeg struct'en som en array med navngitte elementer..

Lenke til kommentar

En mulighet er uansett å bruke pekere til Cell-objekter istedet for å putte dem rett inn i klassa - det gir meg muligheten til å siden "kastrere" AccelStruct klassen ved å slette Cell-objektene samt ymse annet. Cell-objektene kan uansett gjennskapes via argumentene til konstruktøren (de fleste AccelStruct-datterklassene mine har tre-fire konstruktørargumenter som brukes til å finne riktig Cell'er ved å interpolere verdier i en database).

Lenke til kommentar

... men da bør jeg kanskje skrive om noe bakenforliggende kode slik at den returnerer Cell* istedet for Cell, noe som gjør at jeg må kopiere ting hit og dit i ett kjør (mellom ulike biter av stack, stack->heap etc.)...

 

Pekere gir jo mer fleksibilitet (til å krasje programmet og lekke minne på morsomme måter), men grunnen til at jeg helst ville unngå det var for å la Cell-fieldene som dermed blir subfields til objektet ligge med faste offsetts i forhold til klassen, noe som ville unngått ett ekstra pekeroppslag ved hver access til elementene i cellene. Men kanskje storage er viktigere enn speed (kan uansett lett paralellisere med OpenMP o.l.) i dette tilfellet.

Lenke til kommentar

Factory funker ikke her - den klassa jeg har delt er et spesial-tilfelle for debugging (sammenlikne med et tidligere resultat fra et Python-program). Vanligvis henter jeg cellene ut fra en interpolasjonsmetode - f.eks. en lineær n-dimensjonal interpolasjon implementert vha. offsets. Du ønsker *ikke* å se den koden :p

Lenke til kommentar

Om du tolererer overheaden kan du jo alltids bruke brace-initialization og så til medlemmene assigne etterpå. Om den aktuelle koden ikke engang skal i produksjon er det jo absolutt en kurant løsning.

 

Men det er da C++11 - vil helst slippe at noen sitter på en sær kompilator (PGI eller VS eller noe slikt - ymse rart som er i bruk i denne bransjen...) som ikke får det til å kompilere, "fikser" problemet, og så setter grå hår i meg tre uker etterpå - gjerne kombinert med at folk lar være å comit'e i noen måneder fordi det er SKUMMELT å vise fram koden sin :/

 

Tror jeg bare bruker "." initialisering jeg, ut utsetter ombytte til pekere til seinere. Uansett så takk for hjelpen her!

Lenke til kommentar

Nå trenger du ikke å bruke pekere i dette tilfellet; hvis ikke hastighet og minnebrukkrever det da. Cell er jo en ren struktur.

 

 

Hvis du har Cell x = { .... }; og deretter sier Cell y = x; så får du en ren kopiering av innholdet.

 

Eller har C++ klart å kludre det til?

Lenke til kommentar

Nå trenger du ikke å bruke pekere i dette tilfellet; hvis ikke hastighet og minnebrukkrever det da. Cell er jo en ren struktur.

 

 

Hvis du har Cell x = { .... }; og deretter sier Cell y = x; så får du en ren kopiering av innholdet.

 

Eller har C++ klart å kludre det til?

 

Neida, C++ gjør akkurat det du sier (så vidt jeg vet).

 

Grunnen til at jeg begynnte å prate om pekere er at (1) det føles teit å kopiere dataene for hver "return", og (2) jeg kan slette dataene når jeg ikke har behov for dem, og slik renske AcceleratorStructure-klassen for alle lett rekonstruerbare input- og temp-variable og slik bare beholde resultatene, noe som eliminerer behovet for spesielle "resultat-structs".

 

Grunn (3) som kom fram her var at om jeg bruker new for å lage den, så burde jeg kunne initialisere med {...} i samme slengen (muligens new Cell({...}) om jeg husker rett - mye rar syntax ute og rusler).

 

Forøvrig, hvorfor blir "firstCell = {bla, bla, bla, ...}" raskere enn "firstCell.h = bla, firstCell.a = bla"? Kompilatoren burde lage samme maskinkoden uansett...

Lenke til kommentar

Opprett en konto eller logg inn for å kommentere

Du må være et medlem for å kunne skrive en kommentar

Opprett konto

Det er enkelt å melde seg inn for å starte en ny konto!

Start en konto

Logg inn

Har du allerede en konto? Logg inn her.

Logg inn nå
  • Hvem er aktive   0 medlemmer

    • Ingen innloggede medlemmer aktive
×
×
  • Opprett ny...