Const Pointer als Rückgabewert

Gast #3077315
Lesenswert?
• ▲
▼
Ich habe eine große Struktur mit Konfigurationsdaten.

Ich möchte auf die Struktur so zugreifen, dass ich sie nicht aus 
versehen verändern kann, möchte aber nicht nicht die komplette Struktur 
zurückgeben da dies viel zu viel zeit kostet wenn man nur einen wert 
daraus möchte.

Nun sehe ich zwei Lösungen, ein funktioniert sicher ist aber relativ 
aufwendig, bei der anderen bin ich mir nicht sicher ob sie das macht was 
ich möchte. Sprich ob ich nicht "aus Versehen" die Konfiguration 
verändern kann.

Sicher? (leider muss man zwei Sachen updaten und auf Konsistenz prüfen)
1
typdef struct{
2
float bla0;
3
float bla1;
4
float bla2;
5
}conf_struct_t;
6

7
typdef enum{
8
bla0 = 0, bla1 = 1,bla2 = 2
9
}conf_enum_t;
10

11
union{
12
conf_struct_t conf;
13
float *value;
14
}conf_union;
15

16

17
float get_conf(conf_enum_t struct_member){
18
   return conf_union.value[struct_member];
19
}
20

21
//functionsaufruf:
22

23

24
iNeedConf = get_conf(bla1);


elegant?
1
typfdef struct{
2
float bla0;
3
float bla1;
4
float bla2;
5
}conf_t;
6

7
conf_t conf;
8

9
const *conf_t get_conf(void){
10
   return &conf;
11
}
12

13
//functionsaufruf:
14

15

16
iNeedConf = get_conf()->bla2;

sicher aber sehr langsam?
1
typfdef struct{
2
float bla0;
3
float bla1;
4
float bla2;
5
}conf_t;
6

7
conf_t conf;
8

9
conf_t get_conf(void){
10
   return conf;
11
}
12

13
//functionsaufruf:
14

15

16
iNeedConf = get_conf().bla2;
Persönliche Seite #3077621
Lesenswert?
• ▲
▼
Sowas?
1
/* Im Header */
2

3
#include <stdlib.h>
4

5
typdef struct
6
{
7
    float a, b, c;
8
} data_t;
9

10
extern const data_t* get_x (void);
11
extern const data_t* get_y (void);
12
extern const data_t* get_z (size_t);
13

14
#define Z0 (*get_z (0))
15
#define Z1 (*get_z (1))
16
#define Z2 (*get_z (2))
17

18
/* Im C-File */
19

20
static const data_t x = { 1.0, 2.0, 3.0 };
21

22
const data_t* get_x (void)
23
{
24
    return &x;
25
}
26

27
const data_t* get_y (void)
28
{
29
    static const data_t x = { 42.0, 3.14, 0.0 };
30
    return &x;
31
}
32

33
const data_t* get_z (size_t n)
34
{
35
    static const data_t x[] =
36
      {
37
         { 42.0, 3.14, 0.0 },
38
         { 2.0, 0.14,  9.0 },
39
         { 2.0, 3.14, 0.0 }
40
      };
41

42
    if (n >= sizeof (x) / sizeof (*x))
43
       abort();
44

45
    return &x[n];
46
}
#3077909
Lesenswert?
• ▲
▼
Felix schrieb:

> aufwendig, bei der anderen bin ich mir nicht sicher ob sie das macht was
> ich möchte. Sprich ob ich nicht "aus Versehen" die Konfiguration
> verändern kann.

Was hindert dich daran, es einfach auszuprobieren?
1
struct test
2
{
3
  int a;
4
};
5

6
struct test myObj = { 5 };
7

8
const struct test* foo()
9
{
10
  return &myObj;
11
}
12

13

14
void bar( int* v )
15
{
16
  *v = 8;
17
}
18

19
void baz( struct test* v )
20
{
21
  v->a = 8;
22
}
23

24
int main()
25
{
26
  struct test* b;
27

28
  b = foo();
29
  b->a = 8;
30

31
  foo()->a = 9;
32

33
  bar( &(foo()->a) );
34

35
  baz( foo() );
36
}

jags durch den Compiler und sieh dir an was passiert. Probier noch alle 
anderen Sachen aus die dir einfallen, was alles du mit dem Returnwert 
von foo() anstellen könntest um zu versuchen an a ranzukommen und es zu 
verändern.
Gast #3079342
Lesenswert?
• ▲
▼
Johann L. schrieb:
> Das ist undefined in C.
>
> Etwa wenn foo() verwendet wird unter der Annahme daß sich myObj nie
> ändert, myObj aber dennoch geändert wird.

kenne ich so nicht. Kannst Du auf Standard irgendwo verweisen?
wenn volatile in die Definition mit aufgenommen wird, kann ich
dann an ein Zeiger ohne volatile Definition zuweisen bzw implizit
bei Rückgabe bei Funktionen. Etwa so

int const volatile i = 5;
const int * pi;

pi = &i;
const int * foo(void){ return &i; }

Antwort schreiben

Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt. Bitte hier nur auf die ursprüngliche Frage antworten, für neue Fragen einen neuen Beitrag erstellen.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.