Gå til innhold

Foto

Irriterende og tilsynelatende inkonsisten warning fra GCC ved deklarasjon av struct

C og C pluss

22 svar i denne tråden

#1 kyrsjo

kyrsjo

    Bruker

  • Medlemmer
  • 9 468 innlegg
  •   23. mars 2003

Skrevet 4. mars 2013 - 11:53

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.
  • 0

#2 Lycantrophe

Lycantrophe

    Bruker

  • Medlemmer
  • 14 429 innlegg
  •   9. februar 2005

Skrevet 4. mars 2013 - 11:55

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)

Dette innlegget har blitt redigert av Lycantrophe: 4. mars 2013 - 12:03

  • 0
>> And whither then? I cannot say

#3 tomsi42

tomsi42

    Bruker

  • Medlemmer
  • 41 559 innlegg
  •   10. april 2007

Skrevet 4. mars 2013 - 11:59

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.
  • 0

Panalympiker - Flickr

"Only weak pictures need perfection. Strong ones can survive considerable faults." - David Vestal


#4 kyrsjo

kyrsjo

    Bruker

  • Medlemmer
  • 9 468 innlegg
  •   23. mars 2003

Skrevet 4. mars 2013 - 13:36

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. ?
  • 0

#5 Lycantrophe

Lycantrophe

    Bruker

  • Medlemmer
  • 14 429 innlegg
  •   9. februar 2005

Skrevet 4. mars 2013 - 13:37

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

Dette innlegget har blitt redigert av Lycantrophe: 4. mars 2013 - 13:38

  • 0
>> And whither then? I cannot say

#6 kyrsjo

kyrsjo

    Bruker

  • Medlemmer
  • 9 468 innlegg
  •   23. mars 2003

Skrevet 4. mars 2013 - 13:45

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..
  • 0

#7 Lycantrophe

Lycantrophe

    Bruker

  • Medlemmer
  • 14 429 innlegg
  •   9. februar 2005

Skrevet 4. mars 2013 - 13:47

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...7189821#7189821

Dette innlegget har blitt redigert av Lycantrophe: 4. mars 2013 - 13:54

  • 0
>> And whither then? I cannot say

#8 kyrsjo

kyrsjo

    Bruker

  • Medlemmer
  • 9 468 innlegg
  •   23. mars 2003

Skrevet 4. mars 2013 - 13:53

Kan som sagt uansett ikke bruke C++11, selv om POD er langt mer relax'ed der.
  • 0

#9 Lycantrophe

Lycantrophe

    Bruker

  • Medlemmer
  • 14 429 innlegg
  •   9. februar 2005

Skrevet 4. mars 2013 - 13:55

Da ville jeg vært på den sikre siden og brukt struct.field = val
  • 0
>> And whither then? I cannot say

#10 kyrsjo

kyrsjo

    Bruker

  • Medlemmer
  • 9 468 innlegg
  •   23. mars 2003

Skrevet 4. mars 2013 - 13:57

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).
  • 0

#11 tomsi42

tomsi42

    Bruker

  • Medlemmer
  • 41 559 innlegg
  •   10. april 2007

Skrevet 4. mars 2013 - 14:00

En annen mulighet er å kanskje å lage en Cell-Factory som har noen ferdigdefinerte Cell'er ?
  • 0

Panalympiker - Flickr

"Only weak pictures need perfection. Strong ones can survive considerable faults." - David Vestal


#12 kyrsjo

kyrsjo

    Bruker

  • Medlemmer
  • 9 468 innlegg
  •   23. mars 2003

Skrevet 4. mars 2013 - 14:02

... 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.
  • 0

#13 kyrsjo

kyrsjo

    Bruker

  • Medlemmer
  • 9 468 innlegg
  •   23. mars 2003

Skrevet 4. mars 2013 - 14:04

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
  • 0

#14 Lycantrophe

Lycantrophe

    Bruker

  • Medlemmer
  • 14 429 innlegg
  •   9. februar 2005

Skrevet 4. mars 2013 - 14:06

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.

Dette innlegget har blitt redigert av Lycantrophe: 4. mars 2013 - 14:06

  • 0
>> And whither then? I cannot say

#15 kyrsjo

kyrsjo

    Bruker

  • Medlemmer
  • 9 468 innlegg
  •   23. mars 2003

Skrevet 4. mars 2013 - 14:07

For dem som måtte være nyskjerrig, så er det en variant av dette her jeg holder på med:
http://accelconf.web.../html/thppc.htm -> THPPC011
for "Compact LInear Collider" (CLIC), hvor "compact" betyr "bare 48 kilometer lang!" :p
  • 0

#16 Lycantrophe

Lycantrophe

    Bruker

  • Medlemmer
  • 14 429 innlegg
  •   9. februar 2005

Skrevet 4. mars 2013 - 14:10

Kult!
  • 0
>> And whither then? I cannot say

#17 kyrsjo

kyrsjo

    Bruker

  • Medlemmer
  • 9 468 innlegg
  •   23. mars 2003

Skrevet 4. mars 2013 - 14:12

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!
  • 0

#18 Lycantrophe

Lycantrophe

    Bruker

  • Medlemmer
  • 14 429 innlegg
  •   9. februar 2005

Skrevet 4. mars 2013 - 14:17

Det høres fornuftig ut.
  • 0
>> And whither then? I cannot say

#19 tomsi42

tomsi42

    Bruker

  • Medlemmer
  • 41 559 innlegg
  •   10. april 2007

Skrevet 4. mars 2013 - 14:30

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?
  • 0

Panalympiker - Flickr

"Only weak pictures need perfection. Strong ones can survive considerable faults." - David Vestal


#20 kyrsjo

kyrsjo

    Bruker

  • Medlemmer
  • 9 468 innlegg
  •   23. mars 2003

Skrevet 4. mars 2013 - 14:42

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...
  • 0



0 bruker(e) leser denne tråden

0 medlemmer, 0 gjester, 0 skjulte brukere