Forum: Compiler & IDEs Const Pointer als Rückgabewert


von Felix (Gast)


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;

von Johann L. (gjlayde) Benutzerseite


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
}

von Karl H. (kbuchegg)


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.

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Karl Heinz Buchegger schrieb:

> struct test myObj = { 5 };
>
> const struct test* foo()
> {
>   return &myObj;
> }

Das ist undefined in C.

Etwa wenn foo() verwendet wird unter der Annahme daß sich myObj nie 
ändert, myObj aber dennoch geändert wird.

von daniel (Gast)


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; }

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

daniel schrieb:

> kenne ich so nicht.

Stimmt, Denkfehler meinerseits.

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.