kyrsjo Skrevet 4. mars 2013 Del Skrevet 4. mars 2013 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
Lycantrophe Skrevet 4. mars 2013 Del Skrevet 4. mars 2013 (endret) Du bruker en C++11-feature. Prøv med -std=c++0x som den sier. Problemet er at du assigner, ikke deklarerer (og assigner). Edit2: se der ja, Tomsi var før meg (og tydeligere) Endret 4. mars 2013 av Lycantrophe Lenke til kommentar
tomsi42 Skrevet 4. mars 2013 Del Skrevet 4. mars 2013 I Cell.cpp, så deklarerer og initialiseres variablen i samme setning (Cell ret = ...) I AccelStructure biten, så assigner du en struktur til en variable som er deklartert tidligerere. Dette er egentilg ikke lov i C++ før C++11. Lenke til kommentar
kyrsjo Skrevet 4. mars 2013 Forfatter Del Skrevet 4. mars 2013 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
Lycantrophe Skrevet 4. mars 2013 Del Skrevet 4. mars 2013 (endret) Eller en constructor. Vil antagelig bli (hakket) kjappere og. Endret 4. mars 2013 av Lycantrophe Lenke til kommentar
kyrsjo Skrevet 4. mars 2013 Forfatter Del Skrevet 4. mars 2013 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
Lycantrophe Skrevet 4. mars 2013 Del Skrevet 4. mars 2013 (endret) Edit: forresten, kanskje ikke. Mener det var noen forandringer der i C++11. Straks tilbake. Edit: Såfremt constructoren er i tillegg til default constructor bør den holde seg innenfor (C++11) POD. ref: http://stackoverflow.com/questions/4178175/what-are-aggregates-and-pods-and-how-why-are-they-special/7189821#7189821 Endret 4. mars 2013 av Lycantrophe Lenke til kommentar
kyrsjo Skrevet 4. mars 2013 Forfatter Del Skrevet 4. mars 2013 Kan som sagt uansett ikke bruke C++11, selv om POD er langt mer relax'ed der. Lenke til kommentar
Lycantrophe Skrevet 4. mars 2013 Del Skrevet 4. mars 2013 Da ville jeg vært på den sikre siden og brukt struct.field = val Lenke til kommentar
kyrsjo Skrevet 4. mars 2013 Forfatter Del Skrevet 4. mars 2013 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
tomsi42 Skrevet 4. mars 2013 Del Skrevet 4. mars 2013 En annen mulighet er å kanskje å lage en Cell-Factory som har noen ferdigdefinerte Cell'er ? Lenke til kommentar
kyrsjo Skrevet 4. mars 2013 Forfatter Del Skrevet 4. mars 2013 ... 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
kyrsjo Skrevet 4. mars 2013 Forfatter Del Skrevet 4. mars 2013 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 Lenke til kommentar
Lycantrophe Skrevet 4. mars 2013 Del Skrevet 4. mars 2013 (endret) 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. Endret 4. mars 2013 av Lycantrophe Lenke til kommentar
kyrsjo Skrevet 4. mars 2013 Forfatter Del Skrevet 4. mars 2013 For dem som måtte være nyskjerrig, så er det en variant av dette her jeg holder på med: http://accelconf.web.cern.ch/accelconf/IPAC2012/html/thppc.htm -> THPPC011 for "Compact LInear Collider" (CLIC), hvor "compact" betyr "bare 48 kilometer lang!" Lenke til kommentar
kyrsjo Skrevet 4. mars 2013 Forfatter Del Skrevet 4. mars 2013 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
Lycantrophe Skrevet 4. mars 2013 Del Skrevet 4. mars 2013 Det høres fornuftig ut. Lenke til kommentar
tomsi42 Skrevet 4. mars 2013 Del Skrevet 4. mars 2013 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
kyrsjo Skrevet 4. mars 2013 Forfatter Del Skrevet 4. mars 2013 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
Anbefalte innlegg
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 kontoLogg inn
Har du allerede en konto? Logg inn her.
Logg inn nå