Forum: PC-Programmierung c, const und Pointer


von Vlad T. (vlad_tepesch)


Lesenswert?

Hi,
gibt es irgendwelche tricks objekte richtig const zu machen?

beispiel
1
struct A{
2
  int a,b,c;
3
}
4
5
struct AListElement{
6
  A* data;
7
  ListElement* next;
8
}
9
10
typedef AListElement AList;
11
12
13
/**
14
 * this function calcs something
15
 * and should not change the data 
16
 */
17
int calcSomething(const AList* alist)
18
{
19
  alist->data->a = -alist->data->a;
20
  printf("haha - ich kanns ja doch ändern\n");
21
  //[...]
22
}

Gibt es irgend eine Möglichkeit Manipulationen wie die obige zu 
unterbinden?
klar, kann man consts auch wegcasten, aber ich rede davon red ich nicht.
Ich hab hier ziemlich verzweigten, komplexen Code, und würde gerne 
sehen, ob nicht doch irgendwo in den Eingangsdaten rumschrieben wird, 
beziehungsweise sicherstellen, dass dies nicht möglich ist.


das einzige, was mir einfallen würde, wäre alle strukturen doppelt zu 
definieren, einmal mit const zeigern und einmal ohne, und dann 
entsprechend die strukturen umcasten.

Also folgender maßen:
1
struct AConstListElement{
2
  const A* data;
3
  const ListElement* next;
4
}
5
typedef AConstListElement AConstList;
6
7
/**
8
 * this function calcs something
9
 * and should not change the data 
10
 */
11
int calcSomething(const AConstList* alist)
12
{
13
  alist->data->a = -alist->data->a;
14
  printf("heul - kann nicht compiliert werden\n");
15
  //[...]
16
}
17
18
19
void someOtherFunction()
20
{
21
  AList list;
22
  //[...]
23
  int x = calcSomething( (AConstList*)(&list) );
24
}

Ich bewzeifel allerdings, dass dies für größere verschachtelte 
Strukturen handhabbar ist, ganz zu schweigen von den zu pflegenden 
Redundanzen

Gruß
Vlad

von Klaus W. (mfgkw)


Lesenswert?

In C wäre das doch bereits nicht kompilierbar:
1
int calcSomething(const AList* alist)
2
{
3
  alist->data->a = -alist->data->a;
4
  //[...]
5
}
Viel mehr wird in C nicht gehen.


Etwas weiter kann man in C++ gehen (get-/set-Methoden, notfalls cheshire 
cat/pimple etc.).

von Vlad T. (vlad_tepesch)


Lesenswert?

Klaus Wachtler schrieb:
> In C wäre das doch bereits nicht kompilierbar:
???
du meinst jetzt wegen den wegelassenen struct oder dem vergessenen A in 
der Typdefintion und dem Semikolon nach den struktdefinitionen (hatte 
das nur gerade so runtergeschrieben um das Prinzip zu verdeutlichen), 
oder allgemein?

die Compiler die ich bisher hatte, fressen das sonst.

Klaus Wachtler schrieb:
> Etwas weiter kann man in C++ gehen (get-/set-Methoden,
das ist mit klar - bin aber auf C festgelegt

> notfalls cheshire cat/pimple etc.).
???
google spuckt mir dazu nur Bilder niedlicher Tierchen aus.

von Klaus W. (mfgkw)


Lesenswert?

Vlad Tepesch schrieb:
> Klaus Wachtler schrieb:
>> In C wäre das doch bereits nicht kompilierbar:
> ???
> du meinst jetzt wegen den wegelassenen struct oder dem vergessenen A in
> der Typdefintion und dem Semikolon nach den struktdefinitionen (hatte
> das nur gerade so runtergeschrieben um das Prinzip zu verdeutlichen),
> oder allgemein?

ich meine:
1
   const irgendwas *irgendein_cptr = ...;
2
   irgendein_cptr->irgendwasdadrin = ...; // geht nicht, weil const irgendwas*

Wenn dein Compiler das ohne Meckern übersetzt, würde ich mir vielleicht 
einen anderen Compiler suchen...

>
> die Compiler die ich bisher hatte, fressen das sonst.
>
> Klaus Wachtler schrieb:
>> Etwas weiter kann man in C++ gehen (get-/set-Methoden,
> das ist mit klar - bin aber auf C festgelegt
>
>> notfalls cheshire cat/pimple etc.).
> ???
> google spuckt mir dazu nur Bilder niedlicher Tierchen aus.

http://en.wikipedia.org/wiki/Opaque_pointer

von Karl H. (kbuchegg)


Lesenswert?

In C hast du da kaum Chancen, weil du nicht verhindern kannst, dass 
dahergelaufener Code quer durch die Datenstruktur referenziert.

In einem const AList Element ist nun mal nur der Pointer const, aber 
nicht das worauf er zeigt.

Was vielleicht gehen könnte: Die internals der struct verstecken. Ein 
AList Element hat nur einen void Pointer. Damit bleibt dir gar nichts 
anderes übrig, als Zugriffe immer über Funktionen zu führen, die sich 
diesen void Pointer dann zurechtcasten. Und dort hast du dann zumindest 
wieder ein bischen Kontrolle.

>> notfalls cheshire cat/pimple etc.).
> ???
> google spuckt mir dazu nur Bilder niedlicher Tierchen aus.

Das sind Namen für Design Methoden bzw. Design Pattern in C++.

von Klaus W. (mfgkw)


Lesenswert?

Karl Heinz Buchegger schrieb:
>>> notfalls cheshire cat/pimple etc.).
>> ???
>> google spuckt mir dazu nur Bilder niedlicher Tierchen aus.
>
> Das sind Namen für Design Methoden bzw. Design Pattern in C++.

Das sind Namen für Design Methoden bzw. Design Pattern.

Man kann sie in C++ umsetzen, aber auch in C.

von Ben j. (scarab)


Lesenswert?

Wie wäre es mit
1
struct A
2
{
3
  const int a,b,c;
4
}
?

unter IAR EWB habe ich ziemlich komplexe Strukturen als konstant im 
Flash erstellt, mit konstanten Zeigern auf andere Strukturen, Arrays, 
Unions usw.
Die waren dann auch nicht durch Funkionen veränderbar. Auch nicht wenn 
man die Zeiger castet da Harvard-Architektur.

hab dazu immer "__flash" verwendet statt const.

von Stefan E. (sternst)


Lesenswert?

Klaus Wachtler schrieb:
> ich meine:   const irgendwas *irgendein_cptr = ...;
>    irgendein_cptr->irgendwasdadrin = ...; // geht nicht, weil const irgendwas*
>
> Wenn dein Compiler das ohne Meckern übersetzt, würde ich mir vielleicht
> einen anderen Compiler suchen...

Schau dir den original Code nochmal an. "irgendwasdadrin" wird ja gar 
nicht verändert (der Pointer), sondern etwas, auf das "irgendwasdadrin" 
zeigt.

Der OP hätte gerne, dass sich das const quasi von der Struktur auch auf 
Ziele von Pointer innerhalb der Struktur vererbt.

von Klaus W. (mfgkw)


Lesenswert?

ok, aber das geht nicht in C ohne ++.

von Vlad T. (vlad_tepesch)


Lesenswert?

Ben jamin schrieb:
> Die waren dann auch nicht durch Funkionen veränderbar.

veränderbar sollen sie aber bleiben - ebend nur für die richtigen ;)

Stefan Ernst schrieb:
> Der OP hätte gerne, dass sich das const quasi von der Struktur auch auf
> Ziele von Pointer innerhalb der Struktur vererbt.

genau, danke - ich dachte, das hätte ich mit dem Beispiel 
unmissverstädnlich klargemacht, dachte vielleicht gibts hier ja 
irngedwelche Tricks oder macromagic

Karl Heinz Buchegger schrieb:
> Das sind Namen für Design Methoden bzw. Design Pattern in C++.

danke :) vom Bridge-Pattern habe ich schon mal gehört, aber mit den 
Namen konnte ich überhaupt nix anfangen

von Ben j. (scarab)


Lesenswert?

Vlad Tepesch schrieb:
> Ben jamin schrieb:
>> Die waren dann auch nicht durch Funkionen veränderbar.
> veränderbar sollen sie aber bleiben - ebend nur für die richtigen ;)

Achso, dann habe ich das "richtig const machen" wohl falsch verstanden.

Du hast wohl Angst das du Daten aus versehen änderst?

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.