Forum: PC-Programmierung C++ Hilfe "expected"


von Mike B. (mike_b97) Benutzerseite


Lesenswert?

Hi!
1
bool tmp = irgendwas;
2
    if ( t < 0 ) tmp = !tmp;
3
    const Node *near = tmp ? node->nchild : node->pchild;
4
    const Node *far = tmp ? node->pchild : node->nchild;

gibt mir zwei " error: expected unqualified-id before '=' token"
mit dem ^-Zeiger im build-log unter den "="-Zeichen.

Ich bin in C++ nicht bewandert genug, um die const-Zeilen vollständig 
entziffern zu können.

Da werden near und far-pointer auf den bool tmp gesetzt, aber was kommt 
dann ab dem "?" und was bedeutet der Fehler?

von Rolf M. (rmagnus)


Lesenswert?

Mike B. schrieb:
> Ich bin in C++ nicht bewandert genug, um die const-Zeilen vollständig
> entziffern zu können.
>
> Da werden near und far-pointer auf den bool tmp gesetzt, aber was kommt
> dann ab dem "?"

Es werden zwei Zeiger namens near und far mit den Werten von 
node->nchild und node->pchild initialisiert. Welches dabei womit 
initialisiert wird, hängt vom Wert von tmp ab. Wie der ?:-Operator (auch 
ternärer Operator) genannt wird, kannst du sich auch selber rausfinden.

> und was bedeutet der Fehler?

Ich vermute, es fehlt die Einbindung des Headers, der den Typ Node 
beschreibt.

von Mike B. (mike_b97) Benutzerseite


Lesenswert?

Rolf M. schrieb:
> ?:-Operator (auch ternärer Operator) genannt
danke, der Begriff fehlte mir

>> und was bedeutet der Fehler?
>
> Ich vermute, es fehlt die Einbindung des Headers, der den Typ Node
> beschreibt.

weiter vorn im code gibt es schon fehlerfreie Zeilen wie
1
node->nchild = reconstruct_kd_tree(data + 1, naabb, &pnode);
2
node->pchild = reconstruct_kd_tree(pnode, paabb, next);
3
4
sowie die
5
struct Mesh3D::Node {
6
  float plane_d;
7
  NodeData *data;
8
  Node *pchild;
9
  Node *nchild;
10
11
  bool is_leaf() const { return ( pchild == 0 && nchild == 0 ); }
12
};
Ich finde in den ganzen Projektfiles (Suche in files:Projectfiles) keine 
Definition von nchild und pchild.

von Jim M. (turboj)


Lesenswert?

Mike B. schrieb:
> Ich finde in den ganzen Projektfiles (Suche in files:Projectfiles) keine
> Definition von nchild und pchild.

Äh, die stehen buchstäblich 4 Zeilen weiter oben in der struct Node 
drin.
Das ist offenbar eine doppelt verkettete Liste.

Wenn man den -> Operator noch nicht kennt, sollte man unbedingt ein C 
Grundlagenbuch durcharbeiten - die Sprache ist NICHT selbsterklärend.

von Sebastian (Gast)


Lesenswert?

Ist es ein sehr alter compiler (aus Zeiten des protected mode) wo near 
und far noch Schlüsselwörter sind?

von cppbert (Gast)


Lesenswert?

Sebastian schrieb:
> Ist es ein sehr alter compiler (aus Zeiten des protected mode) wo
> near
> und far noch Schlüsselwörter sind?

Muesste far und near dann nicht links vom * stehen

von cppbert (Gast)


Lesenswert?

> Da werden near und far-pointer auf den bool tmp gesetzt, aber was kommt
> dann ab dem "?" und was bedeutet der Fehler?

Unary if nennt man das

Condition ? WennTrue : WennFalse;

Geht auch mit Zuweisung

Result = condition ? WennTrue : WennFalse

Ist nur eine Kurzschreibweise von If die mit const initalisierung 
funktioniert

von mh (Gast)


Lesenswert?

Mike B. schrieb:
> struct Mesh3D::Node {

Vermutlich hat das Problem was mit dem Mesh3D zu tun. Für genauere Infos 
brauchen wir mehr Zusammenhang (== Quelltext).

von Mike B. (mike_b97) Benutzerseite


Lesenswert?

Jim M. schrieb:

> Äh, die stehen buchstäblich 4 Zeilen weiter oben in der struct Node
> drin.
1
  Node *pchild;
2
  Node *nchild;
Do'h!
ich "arbeite" wesentlich häufiger in Pascal und selten in C/C++
in Pascal isses halt
var mynode:Node;
also genau andersrum, ich brauch immer erst 'ne Zeit um umzuschalten, zu 
wenig Übung

> Wenn man den -> Operator noch nicht kennt, sollte man unbedingt ein C
> Grundlagenbuch durcharbeiten
hier noch besser ein C++ Buch

Sebastian schrieb:
> Ist es ein sehr alter compiler (aus Zeiten des protected mode) wo
> near und far noch Schlüsselwörter sind?
der code is schon älter, ja, vermutlich auch mit einem noch älteren 
compiler bearbeitet

Danke erstmal, ich grab weiter.

von Dirk B. (dirkb2)


Lesenswert?

Mike B. schrieb:
> der code is schon älter, ja, vermutlich auch mit einem noch älteren
> compiler bearbeitet

Nein, so war die Frage nicht gemeint.
So:
Hat dein jetziger Compiler evtl. near und/oder far als Schlüsselwort 
reserviert?

von cppbert (Gast)


Lesenswert?

Mike B. schrieb:
>> Ist es ein sehr alter compiler (aus Zeiten des protected mode) wo
>> near und far noch Schlüsselwörter sind?
> der code is schon älter, ja, vermutlich auch mit einem noch älteren
> compiler bearbeitet

Nein eher so richtig alt, DOS,Win3.11,Win95 Zeit, so aus den 80,90er 
jahren - da gab es noch so was wie far und near pointer - aus der 16bit 
Zeit weit vor der 32bit Zeit

Als Antwort reicht hier einfach Name und Version des Ursprünglichen und 
deines jetztigen Kompilers um das aus zu schliessen

von Dirk B. (dirkb2)


Lesenswert?

cppbert schrieb:
> Nein eher so richtig alt, DOS,Win3.11,Win95 Zeit, so aus den 80,90er
> jahren - da gab es noch so was wie far und near pointer - aus der 16bit

Aber far und near sind hier die Bezeichner der Pointer (auf den Typ 
Node).
Bei den 16-Bit Compiler wären das Modifier.

Also eher neuer Code auf altem Compiler. Oder einer der auf alt macht.

von Mike B. (mike_b97) Benutzerseite


Lesenswert?

cppbert schrieb:
> Als Antwort reicht hier einfach Name und Version des Ursprünglichen und
> deines jetztigen Kompilers um das aus zu schliessen

der code ist markiert mit copyright von 2004-2005
ich bearbeite diesen code im Moment
unter Code::Blocks auf einem Win 8.1 64
mit compiler GCC 8.1 aus mingw64, als Target gesetzt ist x86_64

wenn ich die oben genanten const-Zeilen aufsplitte zu
1
          bool tmp = ray.origin[ndata->splitaxis] + node->plane_d < 0;
2
    if ( t < 0 ) tmp = !tmp;
3
    const Node *near node;
4
    if (tmp) {node->nchild} else {node->pchild}
bekomme ich error: expected ';' before '}' token jeweils nach nchild und 
pchild da ihm anscheinend eine Zuweisung wie weiter oben im code
1
    node->nchild = 0;
2
    node->pchild = 0;
fehlt.
(ist const Node *near node; korrekt?)

Hier wird ja quasi nur auf die Member nchild und pchild der struct 
Mesh3D::Node (siehe oben) zugegriffen.

In Pascal also "if tmp then node.nchild else node.pchild;"
Das macht ohne Zuweisung eines Wertes zu node.nchild/node.pchild 
natürlich keinen Sinn, zumindest für mich nicht.
Nicht einmal, wenn ich *near und *far als Unterscheidungsmerkmal nehme.

Der anschließende code lautet
1
  // interval clipped to near side
2
  vec2 new_interval(ray_interval[0], std::min(t, ray_interval[1]));
3
4
  bool isect_found = kd_tree_intersect(ray, new_interval, near, iinfo);
5
  if ( !isect_found ) {
6
    // interval clipped to far side
7
    new_interval[0] = std::max(t, ray_interval[0]);
8
    new_interval[1] = ray_interval[1];
9
    isect_found = kd_tree_intersect(ray, new_interval, far, iinfo);
10
  }
11
12
    return isect_found;
vorher definiert:
1
bool Mesh3D::kd_tree_intersect(
2
  const Ray& ray,
3
  const vec2& ray_interval,
4
  const Node *node,
5
  IntersectionInfo *iinfo
6
)

Ich verstehe programmiertechnisch nicht, warum hier die near und die 
far-Anteile getrennt werden müssen.

p.s. ich hab den source doch noch im inet finden können:
https://github.com/Kochise/3dglrtvr/tree/master/Markus%20Trenkwalder/Raytracer/Raytracer 
(hier unter scenes scene2)

von mh (Gast)


Lesenswert?

Mike B. schrieb:
> Ich verstehe programmiertechnisch nicht, warum hier die near und die
> far-Anteile getrennt werden müssen.

Meinst du das auf Algorithmen- oder Programmiersprachenebene?

Mike B. schrieb:
> p.s. ich hab den source doch noch im inet finden können:
> 
https://github.com/Kochise/3dglrtvr/tree/master/Markus%20Trenkwalder/Raytracer/Raytracer
> (hier unter scenes scene2)

Der ursprüngliche Quelltextfetzen, den du gezeigt hast, stammt aus 
"Raytracer/Raytracer/src/objects/mesh3d.cpp"

Mike B. schrieb:
> Hier wird ja quasi nur auf die Member nchild und pchild der struct
> Mesh3D::Node (siehe oben) zugegriffen.

Warum hast hier das Mesh3D dazugeschrieben? Guck dir nochmal den 
Quelltext (aus dem Orginalpost) und die Fehlermeldung vom Compiler an.

von Mike B. (mike_b97) Benutzerseite


Lesenswert?

mh schrieb:
> Mike B. schrieb:
>> Ich verstehe programmiertechnisch nicht, warum hier die near und die
>> far-Anteile getrennt werden müssen.
>
> Meinst du das auf Algorithmen- oder Programmiersprachenebene?
beides
sein "// determine the near and far nodes" zeigt ja einen 
algorithmentechnischen Inhalt
*near und *far jedoch sind jedoch ebenfalls bereits (alte) 
Schlüsselwörter in C++ zur Speicherverwaltung

> Mike B. schrieb:
>> Hier wird ja quasi nur auf die Member nchild und pchild der struct
>> Mesh3D::Node (siehe oben) zugegriffen.
>
> Warum hast hier das Mesh3D dazugeschrieben?

Weil pchild und nchild member der struct Mesh3D::Node sind. (zeile 54 im 
Code)

> Guck dir nochmal den Quelltext (aus dem Orginalpost) und die
> Fehlermeldung vom Compiler an.
was sagt mir das, was meinst du?

von cppbert (Gast)


Lesenswert?

Mike B. schrieb:
> *near und *far jedoch sind jedoch ebenfalls bereits (alte)
> Schlüsselwörter in C++ zur Speicherverwaltung

LÖSCH das aus deinem Kopf - dafür müsste da far* und near* stehen - ist 
bei dir nicht so und der Code ist viel zu jung als wenn das jemals 
irgendwelche Relevanz gehabt haben könnte

von mh (Gast)


Lesenswert?

Mike B. schrieb:
> mh schrieb:
>> Mike B. schrieb:
>>> Ich verstehe programmiertechnisch nicht, warum hier die near und die
>>> far-Anteile getrennt werden müssen.
>>
>> Meinst du das auf Algorithmen- oder Programmiersprachenebene?
> beides
> sein "// determine the near and far nodes" zeigt ja einen
> algorithmentechnischen Inhalt

Und wo ist da jetzt dein Problem?

Mike B. schrieb:
> *near und *far jedoch sind jedoch ebenfalls bereits (alte)
> Schlüsselwörter in C++ zur Speicherverwaltung

Dann würde aber jeweils der Name der Variable fehlen.

Mike B. schrieb:
> Weil pchild und nchild member der struct Mesh3D::Node sind. (zeile 54 im
> Code)
>
>> Guck dir nochmal den Quelltext (aus dem Orginalpost) und die
>> Fehlermeldung vom Compiler an.
> was sagt mir das, was meinst du?

Lies die Zeilen nochmal genau! Welchen Typ haben near und far?

von cppbert (Gast)


Lesenswert?

Bedenke: du bekommst z.B. auch Fehler mit "=" wenn der Kompiler den Typ 
der Variable der einen Wert zugeordnet werden soll nicht kennt

von Mike B. (mike_b97) Benutzerseite


Lesenswert?

cppbert schrieb:
> Mike B. schrieb:
>> *near und *far jedoch sind jedoch ebenfalls bereits (alte)
>> Schlüsselwörter in C++ zur Speicherverwaltung
>
> LÖSCH das aus deinem Kopf - dafür müsste da far* und near* stehen - ist
> bei dir nicht so und der Code ist viel zu jung als wenn das jemals
> irgendwelche Relevanz gehabt haben könnte

ahhhhhh, also sind *near und *far hier zwei pointer auf Nachfahren von 
Node

das erklärt einiges :D
gut, von hier aus muss ich nachher mal neu weiterdenken
Danke!

: Bearbeitet durch User
Beitrag #6245284 wurde vom Autor gelöscht.
von Rolf M. (rmagnus)


Lesenswert?

near und far können durchaus das Problem sein. Die können sich auch 
durch irgendwelche Windows-Header einschleichen.
In mingw gibt's z.B. diese Datei:
https://github.com/Alexpux/mingw-w64/blob/master/mingw-w64-headers/include/minwindef.h
Da finden sich dann die beiden Zeilen:
1
#define far
2
#define near

Und das würde exakt zu der Fehlermeldung passen. Sprich: Der Code will 
die Namen near und far für ganz normale Variablennamen verwenden, aber 
die Definition aus dem Header sorgt dafür, dass diese beiden Namen durch 
den Präprozessor aus dem Code entfernt werden. Dann fehlt dem 
eigentlichen Compiler der Variablenname (also eine "unqualified id" vor 
dem =), und es kommt zu der gezeigten Fehlermeldung.

Ich würde also versuchsweise mal irgendwo vor der Erzeugung der beiden 
Zeiger
folgendes einfügen:
1
#undef near
2
#undef far

: Bearbeitet durch User
von cppbert (Gast)


Lesenswert?

Rolf M. schrieb:
> near und far können durchaus das Problem sein. Die können sich
> auch
> durch irgendwelche Windows-Header einschleichen.
> In mingw gibt's z.B. diese Datei:
> 
https://github.com/Alexpux/mingw-w64/blob/master/mingw-w64-headers/include/minwindef.h
> Da finden sich dann die beiden Zeilen:#define far
> #define near

ja da könntest du doch wohl recht haben - sehr fiese

von Mike B. (mike_b97) Benutzerseite


Lesenswert?

während
"const Node 'node,"
als Member in "bool Mesh3D::kd_tree_intersect("
funktioniert,
funktionieren im code selbst
weder const Node *near;
noch const Node *near = 0;
noch const Node *near = new Node;

immer undefined_id

Rolf M. schrieb:

> Ich würde also versuchsweise mal irgendwo vor der Erzeugung der beiden
> Zeiger
> folgendes einfügen:
> #undef near
> #undef far

eingefügt ganz oben in der mesh3d.cpp unter
..
#include <string>

using namespace math3d;

neuer code unten
1
const Node *near;
2
  if (tmp)
3
            {
4
                near=node->nchild
5
            }
6
        else
7
            {
8
                *near=node->pchild
9
            }
für die nchild-Zuweisung oben
error: expected ';' before '}' token
                 near==node->nchild
                                   ^
                                   ;
             }
             ~
egal ob near=node->nchild oder near==node->nchild
ich kapiers nicht

von Rolf M. (rmagnus)


Lesenswert?

Mike B. schrieb:
> error: expected ';' before '}' token
>                  near==node->nchild
>                                    ^
>                                    ;
>              }
>              ~
> egal ob near=node->nchild oder near==node->nchild
> ich kapiers nicht

Warum nicht? Der Compiler sagt doch ganz exakt, was fehlt und auch wo. 
Jedes Statement muss in C++ mit einem Semikolon abgeschlossen sein, und 
das fehlt bei dir. Stell den Code doch einfach wieder so um, wie er 
vorher war, nur eben mit den beiden #undef drin. Dann sollte es gehen.

: Bearbeitet durch User
von Mike B. (mike_b97) Benutzerseite


Lesenswert?

Rolf M. schrieb:
> Warum nicht? Der Compiler sagt doch ganz exakt, was fehlt und auch wo.
> Jedes Statement muss in C++ mit einem Semikolon abgeschlossen sein,

boah, wann machen die Optiker wieder auf?
Ich brauch dringend 'ne neue Brille! :D

von cppbert (Gast)


Lesenswert?

Mike B. schrieb:
> using namespace math3d;
>
> neuer code untenconst Node *near;
>   if (tmp)
>             {
>                 near=node->nchild
>             }
>         else
>             {
>                 *near=node->pchild
>             }
> für die nchild-Zuweisung oben
> error: expected ';' before '}' token
>                  near==node->nchild
>                                    ^
>                                    ;
>              }
>              ~
> egal ob near=node->nchild oder near==node->nchild
> ich kapiers nicht

ich garantiere dir das du mit dem bisschen Vorwissen von einem Problem 
ins nächste stolperst - du machst beim Umstellen einen Haufen triviale 
Fehler

Sag uns doch einfach mal was du erreichen willst - stell dir vor du 
müsstes jemanden erklären der das für dich machen soll was du willst - 
was ist dein Ziel - also wenn alles 100% fertig ist?

von Mike B. (mike_b97) Benutzerseite


Lesenswert?

cppbert schrieb:
> ich garantiere dir das du mit dem bisschen Vorwissen von einem Problem
> ins nächste stolperst
das ist garantiert :D

> Sag uns doch einfach mal was du erreichen willst
Lauffähigen code?

Ich will es einmal erleben, dass code, den man sich aus dem inet zieht, 
auf Anhieb funktioniert.
Alles was über "Hello World!" hinausgeht braucht immer erstmal 
stundenlange Frickelei bis es läuft. (2 Jahrzehnte Erfahrung), egal ob 
Pascal, Prolog, C/C++, VB oder sonstwas.

Von Projekten mit GUI-Fremdkomponenten ganz zu schweigen.
:D

von cppbert (Gast)


Lesenswert?

Mike B. schrieb:
> 2 Jahrzehnte Erfahrung

nur eben kein C++ - weil die Fehler die du machst sind Anfänger-Niveau 
:)

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.