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

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