Forum: PC-Programmierung #define mitten im code


von Durchstarter (Gast)


Lesenswert?

Hallo zusammen,

ist es möglich #define mitten im code zu definieren.
1
//gewoehnlich ganz oben
2
if (Quelle A)
3
#define   register register_a
4
elseif(Quelle B)
5
#define   register register_b
6
.
7
.
8
.

je nach dem woher ich meine Daten her kriege (unterschiedliche Quellen) 
muss ich unterschiedliche Register ansprechen. Ich weiss aber nicht von 
vorn herein welcher Sender (Quelle) mir Daten senden wird. Wollte jetzt 
nich unbedingt 10 Funktionen schreiben, eine für jede Quelle, sondern 
wenn ich Daten aus der Quelle A habe sollen alle  Register der Quelle A 
abgearbeitet werden und so weiter...

1
void daten_bearbeiten()
2
{
3
    register.RXREGISTER...
4
}

Danke

Gruß

Dennis

von Klaus W. (mfgkw)


Lesenswert?

Prinzipiell kannst das #define hinschreiben, wo du willst - ob es 
elegant ist, steht auf einem anderen Blatt.

Das was du vorhast geht aber trotzdem nicht.
Grund: Vor dem eigentlichen Kompilieren läuft der Präprozessor durch die 
Datei und kümmert sich u.a. um die #define-Geschichten.
Den interessiert aber dein if nicht, und er weiß auch gar nicht, welcher 
Fall zur Laufzeit eintreten wird.
Also sieht er einfach beide #define und wird beim zweiten meckern, weil 
es ja schon orher eines mit demselben Namen gab.

(Steht in C-Büchern heute nicht mehr, wie der Präprozessor arbeitet?)

von Durchstarter (Gast)


Lesenswert?

So wie ich Sie verstanden habe Hr. Wachtler, sollte ich dieses vorhaben 
sein lassen.
Jut, dann werd ich mal mit dem Schreiben der Funktionen anfangen.

Danke

Gruß

von Rolf Magnus (Gast)


Lesenswert?

Durchstarter schrieb:
> Wollte jetzt nich unbedingt 10 Funktionen schreiben, eine für jede
> Quelle, sondern wenn ich Daten aus der Quelle A habe sollen alle
> Register der Quelle A abgearbeitet werden und so weiter...

Dann verwende einen Zeiger.

von Kurzschlusselektriker (Gast)


Lesenswert?

Vorsicht auch mit "elseif" und "register".
Ob diese wörter so erlaubt sind, hängt von der Sprache und dem Compiler 
ab...
Wenn ich mich nicht irre, gibts in C kein elseif und "register" könnte 
eine Speicherklasse sein ("pack den kram in ein reigster").

von Kurzschlusselektriker (Gast)


Lesenswert?


von Klaus W. (mfgkw)


Lesenswert?

Durchstarter schrieb:
> So wie ich Sie verstanden habe Hr. Wachtler, sollte ich dieses vorhaben
> sein lassen.

ja, so meinte ich das.

Je nachdem, was es genau machen soll, kann in der Tat ein Zeiger das 
richtige Mittel sein.
Das könnte etwa so aussehen (angenommen, die Register haben den Typ 
register_t):
1
    register_t   *p_welchesregister = NULL;
2
    if( irgendwas )
3
    {
4
        p_welchesregister = &register_a;
5
    }
6
    else if( irgendwasanderes )
7
    {
8
        p_welchesregister = &register_b;
9
    }
10
    else if( irgendwasganzanderes )
11
    {
12
        p_welchesregister = &register_c;
13
    }
14
...
15
    daten_bearbeiten( p_welchesregister );
16
....
17
18
void daten_bearbeiten( register_t *p_register )
19
{
20
    if( p_register!=NULL )
21
    {
22
        p_register->RXREGISTER...
23
    }
24
    else
25
    {
26
        // ganz dummer Fehler!
27
        // Meldung ausgeben, Programm abbrechen,
28
        // ab in die Kirche zum Beichten...
29
        ...
30
    }
31
}

von Klaus W. (mfgkw)


Lesenswert?

Kurzschlusselektriker schrieb:
> Wenn ich mich nicht irre, gibts in C kein elseif und "register" könnte
> eine Speicherklasse sein ("pack den kram in ein reigster").

stimmt, register ist ein reserviertes Schlüsselwort.

von Durchstarter (Gast)


Lesenswert?

Vielen Dank

Adieu

von undef (Gast)


Lesenswert?

Natürlich kann man mitten im Code ein #define vereinbaren. Das macht 
sogar Sinn.

z. Bsp.
1
...
2
3
int foo_func (void) {
4
   ...
5
6
#define LOCAL_DEF 123
7
   ...
8
#undef LOCAL_DEF
9
10
   ...
11
}

von Rolf Magnus (Gast)


Lesenswert?

undef schrieb:
> Natürlich kann man mitten im Code ein #define vereinbaren.

Klar. Nur tut das leider nicht das, was "Durchstarter" sich davon 
erwartet hat.

von undef (Gast)


Lesenswert?

Rolf Magnus schrieb:
> Nur tut das leider nicht das, was "Durchstarter" sich davon
> erwartet hat.

Klaus Wachtler schrieb:
> ob es
> elegant ist, steht auf einem anderen Blatt.

ich hatte den Satz von KW im Hinterkopf.

von Klaus W. (mfgkw)


Lesenswert?

Aber auch dann gilt: in den meisten Fällen, wo es verwendet wird, ist 
ein #define inzwischen eher kontraproduktiv.
Funktionsähnliche Makros sowieso, aber auch als Konstanten ist eine 
const int oder sowas meist sinnvoller.

Ausnahmen gibt es sicher, aber um einen Wert zu definieren sehe ich 
eigentlich nur noch zur Übergabe an den Compiler eine Rechtfertigung 
(und damit ist es ja auch kein #define, sondern ein -D... :-)

von undef (Gast)


Lesenswert?

Klaus Wachtler schrieb:
> aber auch als Konstanten ist eine
> const int oder sowas meist sinnvoller.
1
...
2
3
int foo_func (void) {
4
   ...
5
const int foo_const = 123;
6
7
#define LOCAL_DEF 123
8
   ...
9
#undef LOCAL_DEF
10
11
   ...
12
}

Wo legt jeder Compiler foo_const ab?

von Bartli (Gast)


Lesenswert?

Im RAM? Im ROM? Das entscheidet schlussendlich das Linkerskript. Falls 
der Compiler foo_const nicht schon lange wegoptimiert hat.

Habt mal ein bisschen vertrauen in die modernen Compiler, also echt.

von undef (Gast)


Lesenswert?

Bartli schrieb:
> Im RAM? Im ROM?

Ja wo nun?
Ein #define wird garantiert nie RAM belegen.

von Tobi H. (tobi-) Benutzerseite


Lesenswert?

Ein const int wird genau dann RAM belegen, wenn es Sinn macht, nämlich 
z.B. beim debuggen und keinen, wenn man Optimierungen einschaltet. Da 
kann sich jeder gerne im asm-Output (oder debugger) von überzeugen.

von undef (Gast)


Lesenswert?

Tobi H. schrieb:
> Ein const int wird genau dann RAM belegen, wenn es Sinn macht, nämlich
> z.B. beim debuggen und keinen, wenn man Optimierungen einschaltet. Da
> kann sich jeder gerne im asm-Output (oder debugger) von überzeugen.

Das ist aber Compiler abhängig!
Der eine oder andere Compiler wird die lokale const Variable auf den 
Stack legen.

von Bartli (Gast)


Lesenswert?

Und mit solchen Steinzeitcompilern erstellst du täglich Software für 
Systeme mit sowenig RAM, dass du lieber #define verwendest. Ist schon 
klar.

von undef (Gast)


Lesenswert?

Bartli schrieb:
> Und mit solchen Steinzeitcompilern erstellst du täglich Software für
> Systeme mit sowenig RAM

Als Entwickler schadet es nicht zu wissen, wie die genutzten Werkzeuge 
arbeiten. Das kann der Qualität der Produkte förderlich sein ;-)

von Bartli (Gast)


Lesenswert?

Gähn.

Na dann erzähl doch mal, mit was für Compilern du so arbeitest. MSC und 
gcc können es ja wohl kaum sein, die sind schon lange nicht mehr so 
dämlich.

von Klaus W. (mfgkw)


Lesenswert?

undef schrieb:
> Als Entwickler schadet es nicht zu wissen, wie die genutzten Werkzeuge
> arbeiten. Das kann der Qualität der Produkte förderlich sein ;-)

Eben weil es der Qualität nicht förderlich ist, müllt man seinen 
Quelltext nicht mehr unnötig mit Makros zu.
Auch das schadet nicht zu wissen.

Abner jeder, wie er will.
Wenn jeder gute SW schreiben würde, wäre ich arbeitslos.

von Rolf Magnus (Gast)


Lesenswert?

Tobi H. schrieb:
> Ein const int wird genau dann RAM belegen, wenn es Sinn macht, nämlich
> z.B. beim debuggen und keinen, wenn man Optimierungen einschaltet.

Dann muß er aber auch als static deklariert sein.

Klaus Wachtler schrieb:
> Aber auch dann gilt: in den meisten Fällen, wo es verwendet wird, ist
> ein #define inzwischen eher kontraproduktiv.
> Funktionsähnliche Makros sowieso, aber auch als Konstanten ist eine
> const int oder sowas meist sinnvoller.

In C gibt es im Gegensatz zu C++ keine echten Konstanten. Deshalb wird 
#define als Ersatz dafür verwendet. Beispiel:

const int arraysize = 5;
int array[arraysize];

das wird außerhalb einer Funktion eine Fehlermeldung geben, da arraysize 
eben keine Konstante ist. Oder die oft verwendete Definiton von pi:
1
#define PI (4 *atan(1))
wird als globaler const double auch nicht durch den Compiler gehen. Und 
wenn ich in solchen Fällen schon Makros verwende, dann werde ich nicht 
so inkonsistent sein und sie in manchen, aber nicht allen Fällen zu 
benutzen.
Außerdem kann man selektive Compilierung nur mit Makros machen, genauso 
wie z.B. Debug-Funktionen, die Quell-Datei und -Zeile ausgeben oder 
sowas wie MAX(), das den größeren von zwei Werten zurückliefert, und 
zwar ohne sich dabei auf einen einzelnen Typ einzuschränken. Es gibt 
jede Menge Gründe für die Verwendung von Makros in C.  In C++ wurden die 
meisten davon eliminiert.
Außerdem wird const in C recht "entspannt" gesehen. Es kann auch mal 
passieren, daß man die "Konstante" versehentlich ändert, was bei einem 
Makro nicht passiert.

von Klaus W. (mfgkw)


Lesenswert?

Rolf Magnus schrieb:
> Dann muß er aber auch als static deklariert sein.

(falls global)

> In C gibt es im Gegensatz zu C++ keine echten Konstanten. Deshalb wird
> #define als Ersatz dafür verwendet. Beispiel:
>
> const int arraysize = 5;
> int array[arraysize];

Tja, was ist C?
K&R, ISO-C90: ja
C99: nein, da geht das.
C++ natürlich auch.

> Oder die oft verwendete Definiton von pi:#define PI (4 *atan(1))

Bei dem dummen Compiler von undef wäre das natürlich eine Katastrophe, 
der würde jedesmal atan() aufrufen! :-)

> Außerdem kann man selektive Compilierung nur mit Makros machen, genauso
> wie z.B. Debug-Funktionen, die Quell-Datei und -Zeile ausgeben

vollkommen richtig; das ist einer der Fälle, die ich pauschal 
unterschreibe.

> oder sowas wie MAX(),

ja, wobei man dabei halt schon wieder die Makroprobleme hat (++ bei 
Parametern etc.).

> In C++ wurden die
> meisten davon eliminiert.

Gott sei es gedankt.

> Außerdem wird const in C recht "entspannt" gesehen. Es kann auch mal
> passieren, daß man die "Konstante" versehentlich ändert, was bei einem
> Makro nicht passiert.

Oder absichtlich (const volatile...).

----

Ich will auch gar nicht behaupten, daß #define generell böse wäre.
Aber in den meisten Fällen, wo ich eines sehe, ginge es ohne besser.

Ähnlich wie mit goto und anderen Murkserwerkzeugen: man kann es mit 
Bedacht verwenden, die meisten machen es anders.

von Gutdurch (Gast)


Lesenswert?

undef schrieb:
> Tobi H. schrieb:
>> Ein const int wird genau dann RAM belegen, wenn es Sinn macht, nämlich
>> z.B. beim debuggen und keinen, wenn man Optimierungen einschaltet. Da
>> kann sich jeder gerne im asm-Output (oder debugger) von überzeugen.
>
> Das ist aber Compiler abhängig!
> Der eine oder andere Compiler wird die lokale const Variable auf den
> Stack legen.

Und wo kommt sie dann her, diese Konstante und was soll sie auf dem 
Stack? Nein du hast leider keine Ahnung oder benutzt Steinzeittools bzw. 
kommerziellen Mist.

von Klaus W. (mfgkw)


Lesenswert?

Durchstarter schrieb:
> Hallo zusammen,
>
> ist es möglich #define mitten im code zu definieren.
> //gewoehnlich ganz oben
> if (Quelle A)
> #define   register register_a
> elseif(Quelle B)
> #define   register register_b
> .
> .
> .
>
> je nach dem woher ich meine Daten her kriege (unterschiedliche Quellen)
> muss ich unterschiedliche Register ansprechen. Ich weiss aber nicht von
> vorn herein welcher Sender (Quelle) mir Daten senden wird.

Oder mal eine andere Interpretation:
Vielleicht weißt du noch nicht beim Schreiben des Quelltextes, welche 
"Quelle" du hast, aber zumindest beim letzlichen Kompilieren (also nicht 
erst zur Laufzeit)?

Dann gibt es vielleicht noch etwas in der von dir gewünschten Art:
1
// heute kompilieren wir mit RS232, morgen mit CAN, übermorgen mache
2
// ich der Königin ein Kind...
3
#define QUELLE_IST_RS232
4
//#define QUELLE_IST_CAN
5
//#define QUELLE_IST_KOENIGIN
6
7
#ifdef QUELLE_IST_RS232
8
#define REGISTER    (register_a)
9
#elif defined QUELLE_IST_CAN
10
#define REGISTER    (register_b)
11
#elif ... etc.
12
#endif
13
14
...

Anstatt des ersten #define QUELLE... könnte man den Compiler dann auch 
z.B.mit -DQUELLE_IST_RS232 aufrufen und so mal die eine und mal die 
andere Version kompilieren.

von Tobi H. (tobi-) Benutzerseite


Lesenswert?

> Oder die oft verwendete Definiton von pi:#define PI (4 *atan(1))
pi wird z.B. beim gcc als zahl definiert...

> oder sowas wie MAX(),
std::max() sollte nicht langsamer sein und genauso allgemeingültig (c++ 
vorausgesetzt). ganz ohne parameter-probleme

> Anstatt des ersten #define QUELLE... könnte man den Compiler dann auch
> z.B.mit -DQUELLE_IST_RS232 aufrufen und so mal die eine und mal die
> andere Version kompilieren.
Klar, bedingte Kompolierung bezweifelt niemand. Aber warum zwischen den 
Blöcken nicht ein
1
const int REGISTER = register_a;
schreiben? Schon sind die defines auf das nötigste reduziert.

Gottseidank wird der neue c++-Standard noch mehr Einsatzzwecke 
ausräumen, dann bleibt absolut nur noch die bedingte Kompilierung

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

#define oder #include im Code können durchaus zweckmässig sein.

Hier ein Beispiel aus den avr-binutils:

opcode/avr.h
1
AVR_INSN (clc,  "",    "1001010010001000", 1, AVR_ISA_1200, 0x9488)
2
AVR_INSN (clh,  "",    "1001010011011000", 1, AVR_ISA_1200, 0x94d8)
3
AVR_INSN (cli,  "",    "1001010011111000", 1, AVR_ISA_1200, 0x94f8)
4
...

Und das kann dann an mehreren Stellen verwendet werden wie zB

gas/config/tc-avr.c
1
#define AVR_INSN(NAME, CONSTR, OPCODE, SIZE, ISA, BIN) \
2
{#NAME, CONSTR, OPCODE, SIZE, ISA, BIN},
3
4
struct avr_opcodes_s avr_opcodes[] =
5
{
6
  #include "opcode/avr.h"
7
  {NULL, NULL, NULL, 0, 0, 0}
8
};
9
10
#undef AVR_INSN

Ähnliche Konstrukte gibt's in avr-gcc.  Eine Struktur anzulegen und 
darauf zuzugreifen ist hier nicht unbedingt zielführend, da etwa auch 
opt-Dateien, welche gültige Komandozeilen-optionen wie -mmcu= enthalten 
und nicht in C-Syntax sind, dadurch abgebildet werden können.

von ... (Gast)


Lesenswert?

Tobi H. schrieb:
> Klar, bedingte Kompolierung bezweifelt niemand. Aber warum zwischen den
> Blöcken nicht ein
>   const int REGISTER = register_a;
> schreiben?
Weil das in dem Zusammenhang dann völliger Schwachsinn ist.

Wenn schon, dann:
1
const int REGISTER_PTR = &register_a;

von ... (Gast)


Lesenswert?

... schrieb:
> Wenn schon, dann:
>    const int REGISTER_PTR = &register_a;

Mist, ist natürlich genauso daneben.
So wird ein Schuh draus:
1
const int * REGISTER_PTR = &register_a;

von undef (Gast)


Lesenswert?

Bartli schrieb:
> Na dann erzähl doch mal, mit was für Compilern du so arbeitest. MSC und
> gcc können es ja wohl kaum sein, die sind schon lange nicht mehr so
> dämlich.

Klaus Wachtler schrieb:
> Bei dem dummen Compiler von undef

Gutdurch schrieb:
> Und wo kommt sie dann her, diese Konstante und was soll sie auf dem
> Stack? Nein du hast leider keine Ahnung oder benutzt Steinzeittools bzw.
> kommerziellen Mist.

Solchen sachlichen und wissenschaftlich fundierten Argumenten kann man 
ja nichts mehr entgegnen. ;-P

Da ich aber gerade ein jungfräuliches Visual C++ (2010) unter die Finger 
bekam, konnte ich mich dem Beweis eures übermächtigen Wissens nicht 
entziehen:
1
#include "stdafx.h"
2
3
4
void foo_func (void)
5
{
6
  const int i = 0x0F0F;
7
8
  for (int n = 0; n < i; n++)
9
  {
10
    n++;
11
    n--;
12
  }
13
}
ergibt
1
;  COMDAT ?foo_func@@YAXXZ
2
_TEXT  SEGMENT
3
_n$5259 = -20            ; size = 4
4
_i$ = -8            ; size = 4
5
?foo_func@@YAXXZ PROC          ; foo_func, COMDAT
6
; Line 5
7
  push  ebp
8
  mov  ebp, esp
9
  sub  esp, 216        ; 000000d8H
10
  push  ebx
11
  push  esi
12
  push  edi
13
  lea  edi, DWORD PTR [ebp-216]
14
  mov  ecx, 54          ; 00000036H
15
  mov  eax, -858993460        ; ccccccccH
16
  rep stosd
17
; Line 6
18
  mov  DWORD PTR _i$[ebp], 3855    ; 00000f0fH
19
; Line 8
20
  mov  DWORD PTR _n$5259[ebp], 0
21
  jmp  SHORT $LN3@foo_func
22
$LN2@foo_func:
23
  mov  eax, DWORD PTR _n$5259[ebp]
24
  add  eax, 1
25
  mov  DWORD PTR _n$5259[ebp], eax
26
$LN3@foo_func:
27
  cmp  DWORD PTR _n$5259[ebp], 3855    ; 00000f0fH
28
  jge  SHORT $LN4@foo_func
29
; Line 10
30
  mov  eax, DWORD PTR _n$5259[ebp]
31
  add  eax, 1
32
  mov  DWORD PTR _n$5259[ebp], eax
33
; Line 11
34
  mov  eax, DWORD PTR _n$5259[ebp]
35
  sub  eax, 1
36
  mov  DWORD PTR _n$5259[ebp], eax
37
; Line 12
38
  jmp  SHORT $LN2@foo_func
39
$LN4@foo_func:
40
; Line 13
41
  pop  edi
42
  pop  esi
43
  pop  ebx
44
  mov  esp, ebp
45
  pop  ebp
46
  ret  0
47
?foo_func@@YAXXZ ENDP          ; foo_func
48
_TEXT  ENDS

und
1
#include "stdafx.h"
2
3
4
void foo_func (void)
5
{
6
#define i  0x0F0F
7
8
  for (int n = 0; n < i; n++)
9
  {
10
    n++;
11
    n--;
12
  }
13
14
#undef i
15
}
ergibt
1
;  COMDAT ?foo_func@@YAXXZ
2
_TEXT  SEGMENT
3
_n$5258 = -8            ; size = 4
4
?foo_func@@YAXXZ PROC          ; foo_func, COMDAT
5
; Line 5
6
  push  ebp
7
  mov  ebp, esp
8
  sub  esp, 204        ; 000000ccH
9
  push  ebx
10
  push  esi
11
  push  edi
12
  lea  edi, DWORD PTR [ebp-204]
13
  mov  ecx, 51          ; 00000033H
14
  mov  eax, -858993460        ; ccccccccH
15
  rep stosd
16
; Line 8
17
  mov  DWORD PTR _n$5258[ebp], 0
18
  jmp  SHORT $LN3@foo_func
19
$LN2@foo_func:
20
  mov  eax, DWORD PTR _n$5258[ebp]
21
  add  eax, 1
22
  mov  DWORD PTR _n$5258[ebp], eax
23
$LN3@foo_func:
24
  cmp  DWORD PTR _n$5258[ebp], 3855    ; 00000f0fH
25
  jge  SHORT $LN4@foo_func
26
; Line 10
27
  mov  eax, DWORD PTR _n$5258[ebp]
28
  add  eax, 1
29
  mov  DWORD PTR _n$5258[ebp], eax
30
; Line 11
31
  mov  eax, DWORD PTR _n$5258[ebp]
32
  sub  eax, 1
33
  mov  DWORD PTR _n$5258[ebp], eax
34
; Line 12
35
  jmp  SHORT $LN2@foo_func
36
$LN4@foo_func:
37
; Line 15
38
  pop  edi
39
  pop  esi
40
  pop  ebx
41
  mov  esp, ebp
42
  pop  ebp
43
  ret  0
44
?foo_func@@YAXXZ ENDP          ; foo_func
45
_TEXT  ENDS

uuuuuupppsss, da fehlt ja der asm Code für die Line 6. Was macht der 
wohl im 'const' Beispiel?

von ... (Gast)


Lesenswert?

Du hast aber nicht zufällig einen Debug-Build kompiliert?
Schalt Dein Visual C++ mal auf "Release" und schau nochmal.

von Bartli (Gast)


Lesenswert?

> Du hast aber nicht zufällig einen Debug-Build kompiliert?

Natürlich ist das ein Debug-Build. Sieht man ja schon daran, wie immer 
schön brav alle Variablen in den Speicher zurückgschrieben werden.

Mein VS2008 optimiert im Release-Build foo_func komplett weg.
1
void foo_func (void)
2
{
3
  const int i = 0x0F0F;
4
  int n;
5
6
  for (n = 0; n < i; n++)
7
  {
8
    n++;
9
    n--;
10
  }
11
}
12
13
int main(int argc, char **argv)
14
{
15
  foo_func();
16
}

=>
1
--- c:\users\xxx\desktop\test\test\test.c --------------------------------------
2
void foo_func (void)
3
{
4
  const int i = 0x0F0F;
5
  int n;
6
7
  for (n = 0; n < i; n++)
8
  {
9
    n++;
10
    n--;
11
  }
12
}
13
14
int main(int argc, char **argv)
15
{
16
  foo_func();
17
}
18
00241000  xor         eax,eax 
19
00241002  ret              
20
--- f:\dd\vctools\crt_bld\self_x86\crt\src\intel\secchk.c ----------------------

> Solchen sachlichen und wissenschaftlich fundierten Argumenten kann man
> ja nichts mehr entgegnen. ;-P

Scherzkeks. Dein Beweis oben ist ja sowas von wissenschaftlich.

von Rolf Magnus (Gast)


Lesenswert?

Klaus Wachtler schrieb:
>> In C gibt es im Gegensatz zu C++ keine echten Konstanten. Deshalb wird
>> #define als Ersatz dafür verwendet. Beispiel:
>>
>> const int arraysize = 5;
>> int array[arraysize];
>
> Tja, was ist C?

Offiziell gibt es nur eins, nämlich C99. Deswegen ist das für mich immer 
die Referenz.

> K&R, ISO-C90: ja
> C99: nein, da geht das.

nein, tut es nicht. Wenn ich die obigen beiden Zeilen in eine Datei 
schreibe, meint gcc -std=c99 dazu zurecht:
1
klaus.c:2:5: error: variably modified ‘array’ at file scope

man beachte meinen von dir geschickterweise nicht mitzitierten Satz "das 
wird außerhalb einer Funktion eine Fehlermeldung geben". Wenn das 
Array lokal und nicht statisch ist, ist das natürlich was anderes, aber 
nur weil C99 für diesen Fall die Möglichkeit bietet, auch nichtkonstante 
Arraygrößen anzugeben.

> C++ natürlich auch.

Da geht es, weil arraysize in C++ eine echte Konstante ist, und nicht 
nur eine Variable mit der Bitte, sie nicht zu beschreiben.

>> Oder die oft verwendete Definiton von pi:#define PI (4 *atan(1))
>
> Bei dem dummen Compiler von undef wäre das natürlich eine Katastrophe,
> der würde jedesmal atan() aufrufen! :-)

Zum Glück nutze ich solche Compiler nicht.

Tobi H. schrieb:
>> Oder die oft verwendete Definiton von pi:#define PI (4 *atan(1))
> pi wird z.B. beim gcc als zahl definiert...

Beim gcc wird pi gar nicht definiert. Höchstens die von dir verwendete 
libc tut das, und wenn sie es in math.h tut, ist das auch noch ein 
Verstoß gegen die ISO-Norm.

>> oder sowas wie MAX(),
> std::max() sollte nicht langsamer sein und genauso allgemeingültig (c++
> vorausgesetzt).

Es geht aber nicht um C++.

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Klaus Wachtler schrieb:
> Rolf Magnus schrieb:
>> Oder die oft verwendete Definiton von pi:#define PI (4 *atan(1))
>
> Bei dem dummen Compiler von undef wäre das natürlich eine Katastrophe,
> der würde jedesmal atan() aufrufen! :-)

Das Ergebnis ist doch vom eingestellten Rounding-Mode abhängig?

von undef (Gast)


Lesenswert?

Bartli schrieb:
> Mein VS2008 optimiert im Release-Build foo_func komplett weg.

Mensch Bartli, du hast es immer noch nicht verstanden: const <irgendwas> 
ist für den Compiler eine Variabl. #define USW sieht er nicht, da der 
Präprozessor den Text ersetzt. Es spielt doch keine Rolle, ob hinterher 
optimiert wird oder nicht.

Das ist wie in der Schule bei Mathe: Wenn dun das richtige Ergebnis vom 
Nachbarn abschreibst, hast du aber den Rechenweg nicht verstanden. Was 
machst du mal ohne Tischnachbarn?

Für mich ist das Thema jetzt abgeschlossen.

von Klaus W. (mfgkw)


Lesenswert?

Gottseidank.

von Bartli (Gast)


Lesenswert?

> Mensch Bartli, du hast es immer noch nicht verstanden.

Na dann ist ja gut und deine Welt wieder in Ordnung.

> Als Entwickler schadet es nicht zu wissen, wie die genutzten Werkzeuge
> arbeiten. Das kann der Qualität der Produkte förderlich sein ;-)

Genau. Einfach mal ausprobieren: Release-Build deiner Saftware bauen und 
staunen wie schnell das plötzlich alles läuft. Du bist ja echt ein 
Spassvogel.

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.