#define - initializer element is not constant

Moderator Persönliche Seite #6270752
Lesenswert?

Garantiert nicht an dieser Stelle.

Das ist ein Präprozessormakro, dessen Syntax völlig korrekt ist. Aber 
ein Makro macht nur 'ne Textersetzung, der Fehler wird irgendwo in dem 
Kontext auftreten, wo du ihn verwendest.

Also: bitte ein compilierbares Minimalbeispiel, oder zumindest 
ausreichend Code, dass man sich ein Bild machen kann.
#6270956
Lesenswert?

Ich schließe mich auch an. Meine Glaskugel meint: samplesPerWave ist 
eine globale oder statische Variable, und toneFreq ist auch eine 
Variable. In dem Fall kann man das nicht so schreiben, weil 
samplesPerWave statisch initialisiert werden muss, also nicht mit einer 
Variablen.
Immerhin kann man anhand der Fehlermeldung erahnen, dass es sich 
anscheinend um C handelt. In C++ wäre es anders…
#6271633
Lesenswert?

MaWin schrieb:
> !Aber die Meldung ist wieder so 'ne totale C-Sch....!

Was zuerst gepostet wurde, war ja auch nur die halbe Meldung. Der 
eigentlich wichtige Teil kam erst nachträglich. Das Makro hat eigentlich 
mit dem Problem nichts zu tun, aber dass das trotzdem als Fehlerquelle 
genannt wird, liegt nicht an der Sprache selbst, sondern am Compiler.
#6271659
Lesenswert?

Wolfgang schrieb:
> Wie Jörg schon richtig schrieb, die #define Zeile ist völlig korrekt.

Ich auch:

Rolf M. schrieb:
> Das Makro hat eigentlich mit dem Problem nichts zu tun

Wolfgang schrieb:
> Was mäkelt der Compiler also daran rum, statt sich auf die wesentliche
> Stelle zu beschänken.

Auch das habe ich geschrieben (nachdem jemand meinte, die Meldung sei 
"wieder so 'ne totale C-Sch....":

Rolf M. schrieb:
> aber dass das trotzdem als Fehlerquelle genannt wird, liegt nicht an der
> Sprache selbst, sondern am Compiler.
Moderator Persönliche Seite #6271683
Lesenswert?

Wolfgang schrieb:
> Was mäkelt der Compiler also daran rum, statt sich auf die wesentliche
> Stelle zu beschänken.

Solange wir hier nur Häppchen serviert bekommen, kann man sich darüber 
überhaupt kein Urteil erlauben. Gemecker auf den Compiler ist völlig 
unangebracht: der versucht, das Subjekt zwischen Tastatur und Stuhl 
darauf hinzuweisen, wo er vermutet, dass der Fehler sein könnte. Das ist 
keine Aufforderung, bei der Interpretation die kleinen grauen Zellen 
abzuschalten und den Blick für den Gesamtzusammenhang zu verlieren.

Wenn jemand Unsinn hin schreibt, der gemäß Sprachdefinition nicht 
umsetzbar ist, dann ist nicht der Compiler dran schuld. Vermutlich 
liegt es an den unzulänglichen Kenntnissen besagten Subjekts. Dieses 
wiederum täte gut daran, sich hier nicht jede Zeile seines fraglichen 
Quellcodes aus der Nase ziehen zu lassen, wenn es denn auf Hilfe bedacht 
wäre.
Moderator #6271690
Lesenswert?

Wolfgang schrieb:
> Wie Jörg schon richtig schrieb, die #define Zeile ist völlig korrekt.

Sehr wahrscheinlich ist sie korrekt, aber absolut hundertprozentig
sicher ist das nicht.

> Was mäkelt der Compiler also daran rum, statt sich auf die wesentliche
> Stelle zu beschänken.

Wäre das Makro bspw. definiert als

1
#define SAMPLINGRATE 1 || 1

oder

1
#define SAMPLINGRATE 1 ? 1 : 1

wäre der Ausdruck

1
SAMPLINGRATE / toneFreq

auch mit variablem toneFreq konstant, und es gäbe keine Fehlermeldung.

Natürlich ist es hier unwahrscheinlich, dass sich der Programmierer in
der Makrodefinition geirrt hat. Da der Compiler sich damit schwer tut,
Wahrscheinlichkeiten zu möglichen Fehlerursachen zu bestimmen (zumal er
die Programmiergewohnheiten seines Gegenüber nicht kennt), tippt er eben
hin und wieder daneben. Im vorliegenden Fall zeigt er immerhin beide
potentiell fehlerhaften Zeilen an, so dass es dem Programmierer nicht
allzu schwer fallen sollte, diejenige mit dem Fehler herauszufinden.
#6271822
Lesenswert?

Yalu X. schrieb:
> Natürlich ist es hier unwahrscheinlich, dass sich der Programmierer in
> der Makrodefinition geirrt hat. Da der Compiler sich damit schwer tut,
> Wahrscheinlichkeiten zu möglichen Fehlerursachen zu bestimmen (zumal er
> die Programmiergewohnheiten seines Gegenüber nicht kennt), tippt er eben
> hin und wieder daneben.

Die Makros werden aber eh lange vor der Übersetzung der Initialisierung 
aufgelöst. Der Compiler muss also nicht raten, was in dem Makro steht. 
Für ihn steht zu diesem Zeitpunkt dort:
1
float samplesPerWave = 22050 / toneFreq:

Da wundert man sich schon, dass er als Ursache erstmal die 22050 
annimmt, die  auf das Makro zurückverfolgt und dann das als 
Fehlerursache meldet.
Ich vermute aber, dass er sich einfach auf den kompletten Initializer 
bezieht und den Anfang davon nimmt. Dann stellt er fest, dass das aus 
einem Makro kommt und gibt dann fälschlicherweise das als Ursache an.
Dazu passt auch, dass obige Zeile zu folgendem Fehler führt:
1
noconstinit.c:2:24: error: initializer element is not constant
2
    2 | float samplesPerWave = 22050 / toneFreq:
3
      |                        ^~~~~
Er zeigt hier auch auf die 22050 (Beziehungsweise eigentlich dann auf 
den kompletten Term "22050 / toneFreq") und nicht direkt auf toneFreq.
Ich sehe das daher als Bug des Compilers in der Rückverfolgung zum 
Makro.

> Im vorliegenden Fall zeigt er immerhin beide potentiell fehlerhaften Zeilen
> an, so dass es dem Programmierer nicht allzu schwer fallen sollte, diejenige
> mit dem Fehler herauszufinden.

Allerdings meldet er in beiden die falsche Stelle als Ursache des 
Fehlers.
Moderator #6271868
Lesenswert?

Rolf M. schrieb:
> Allerdings meldet er in beiden die falsche Stelle als Ursache des
> Fehlers.

Das stimmt.

Clang markiert im Gegensatz zum GCC den kompletten Ausdruck. Außerdem
bezieht sich dort der Error auf die Initialisierung und die Note auf die
Makrodefinition, beim GCC ist es genau anders herum. Die Clang-Meldung
ist also insgesamt treffender.

GCC:

1
test.c:5:22: error: initializer element is not constant
2
    5 | #define SAMPLINGRATE 22050
3
      |                      ^~~~~
4
test.c:15:24: note: in expansion of macro ‘SAMPLINGRATE’
5
   15 | float samplesPerWave = SAMPLINGRATE / toneFreq;
6
      |                        ^~~~~~~~~~~~

Clang:

1
test.c:15:24: error: initializer element is not a compile-time constant
2
float samplesPerWave = SAMPLINGRATE / toneFreq;
3
                       ^~~~~~~~~~~~~~~~~~~~~~~
4
test.c:5:22: note: expanded from macro 'SAMPLINGRATE'
5
#define SAMPLINGRATE 22050
6
                     ^
Beitrag #6272010 wurde von einem Moderator gelöscht.
Beitrag #6272128 wurde von einem Moderator gelöscht.
OP #6272574
Lesenswert?

Alles  gut, ich bin natürlich noch hier. Ich hatte nur versucht das 
Problem in der Zwischenzeit mit Büchern zu lösen. Sonst gibts wieder 
Schellen von Karl-Heinz :)

Also:
1
//sub.c
2
#include <stdio.h>
3
#include <stdlib.h>
4
#include <string.h>
5

6
#define SAMPLINGRATE 22050
7

8
  int zahl = 5;
9
  char string_array[100];
10

11
  float toneFreq = 1.f;
12
  float samplesPerWave = SAMPLINGRATE / toneFreq;
13

14
void a_task() {
15

16
  strcpy(string_array, "Hallo");
17
  printf("%f\n", samplesPerWave );
18

19
}
1
Scanning dependencies of target __idf_main
2
[ 98%] Building C object esp-idf/main/CMakeFiles/__idf_main.dir/sub.c.obj
3
/ESP32/projekte/test/main/sub.c:6:22: error: initializer element is not constant
4
 #define SAMPLINGRATE 22050
5
                      ^~~~~
6
/ESP32/projekte/test/main/sub.c:12:31: note: in expansion of macro 'SAMPLINGRATE'
7
  const float samplesPerWave = SAMPLINGRATE / toneFreq;
8
                               ^~~~~~~~~~~~

Wobei, das funktioniert:
1
//sub.c
2
#include <stdio.h>
3
#include <stdlib.h>
4
#include <string.h>
5

6
#define SAMPLINGRATE 22050
7

8
  int zahl = 5;
9
  char string_array[100];
10

11
void a_task() {
12

13
  strcpy(string_array, "Hallo");
14

15
  float toneFreq = 1.f;
16
  float samplesPerWave = SAMPLINGRATE / toneFreq;
17
  printf("%f\n", samplesPerWave );
18

19
}
1
5
2
22050.000000
3
Hallo

Danke für die rege Teilnahme :)
Beitrag #6272790 wurde von einem Moderator gelöscht.

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