c, const und Pointer

OP #2557655
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
OP #2557689
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.
#2557767
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
#2557773
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++.
#2557883
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.
#2557893
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.
OP #2557989
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

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren