#define - initializer element is not constant

Moderator Persönliche Seite #6270752
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.
OP #6270775
Sorry.
1
#define SAMPLINGRATE 22050
2

3
main/sound.c:10:22: error: initializer element is not constant
4
 #define SAMPLINGRATE 22050
5
                      ^~~~~
6
main/sound.c:109:24: note: in expansion of macro 'SAMPLINGRATE'
7
 float samplesPerWave = SAMPLINGRATE / toneFreq;
8
                        ^~~~~~~~~~~~
#6270956
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…
Gast #6271411
Rolf M. schrieb:
> samplesPerWave ist
> eine globale oder statische Variable, und toneFreq ist auch eine
> Variable. In dem Fall kann man das nicht so schreiben

Richtig, kann der Compiler so nicht auflösen.

!Aber die Meldung ist wieder so 'ne totale C-Sch....!
#6271633
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.
Gast #6271650
Rolf M. schrieb:
> Was zuerst gepostet wurde, war ja auch nur die halbe Meldung.

Wie Jörg schon richtig schrieb, die #define Zeile ist völlig korrekt. 
Was mäkelt der Compiler also daran rum, statt sich auf die wesentliche 
Stelle zu beschänken.

Jörg W. schrieb:
> Das ist ein Präprozessormakro, dessen Syntax völlig korrekt ist.
#6271659
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
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
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
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.
#6271843
Der Fehler müsste sich doch dadurch beheben lassen, dass man in der 
einen Zeile die Variable definiert und in einer weiteren initialisiert.
Der Compiler würde doch gerne einfach einen festen Wert in die Variable 
schreiben, was nicht für "toneFreq" gilt.
Moderator #6271868
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
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

Eine eigene Frage? Dieser Thread ist über 6 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

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.