Forum: Compiler & IDEs #define - initializer element is not constant


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von W3ll S. (w3llschmidt)


Bewertung
-1 lesenswert
nicht lesenswert
Uhh?

#define SAMPLINGRATE 22050

error: initializer element is not constant

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Bewertung
3 lesenswert
nicht 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.

von Oliver S. (oliverso)


Bewertung
0 lesenswert
nicht lesenswert
Dann wird’s wohl so sein.

Oliver

von W3ll S. (w3llschmidt)


Bewertung
0 lesenswert
nicht lesenswert
Sorry.
#define SAMPLINGRATE 22050

main/sound.c:10:22: error: initializer element is not constant
 #define SAMPLINGRATE 22050
                      ^~~~~
main/sound.c:109:24: note: in expansion of macro 'SAMPLINGRATE'
 float samplesPerWave = SAMPLINGRATE / toneFreq;
                        ^~~~~~~~~~~~

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Bewertung
2 lesenswert
nicht lesenswert
Da fehlt immer noch Kontext, insbesondere, an welcher Stelle dein 
samplesPerWave denn definiert werden soll (global oder innerhalb einer 
Funktion).

Vermutung: toneFreq ist eine Variable und ist das eigentliche Übel hier.

von Yalu X. (yalu) (Moderator)


Bewertung
1 lesenswert
nicht lesenswert
Ich schließe mich Jörgs Vermutung an.

: Wiederhergestellt durch Moderator
von Rolf M. (rmagnus)


Bewertung
0 lesenswert
nicht 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…

von MaWin (Gast)


Bewertung
0 lesenswert
nicht lesenswert
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....!

von Rolf M. (rmagnus)


Bewertung
0 lesenswert
nicht 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.

von Wolfgang (Gast)


Bewertung
0 lesenswert
nicht lesenswert
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.

von Rolf M. (rmagnus)


Bewertung
0 lesenswert
nicht 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.

: Bearbeitet durch User
von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Bewertung
2 lesenswert
nicht 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.

von Yalu X. (yalu) (Moderator)


Bewertung
1 lesenswert
nicht 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

#define SAMPLINGRATE 1 || 1

oder

#define SAMPLINGRATE 1 ? 1 : 1

wäre der Ausdruck

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.

: Bearbeitet durch Moderator
von MaWin (Gast)


Bewertung
-2 lesenswert
nicht lesenswert
> von MaWin (Gast) 19.05.2020 23:57

Mal wieder ein Rant-Beitrag des Psychopathen, der seinen Namen nicht 
kennt und stattdessen MaWin reinschreibt.

von Rolf M. (rmagnus)


Bewertung
0 lesenswert
nicht 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:
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:
noconstinit.c:2:24: error: initializer element is not constant
    2 | float samplesPerWave = 22050 / toneFreq:
      |                        ^~~~~
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.

: Bearbeitet durch User
von Rahul D. (rahul)


Bewertung
0 lesenswert
nicht lesenswert
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.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Bewertung
0 lesenswert
nicht lesenswert
Rahul D. schrieb:
> dass man in der einen Zeile die Variable definiert und in einer weiteren
> initialisiert.

Das ist dann keine Initialisierung mehr, sondern eine Zuweisung – und 
damit syntaktisch schon wieder was anderes.

Solange der TE nicht mit paar Zeilen Details mehr rausrückt, ist ihm 
nicht zu helfen.

von Rolf M. (rmagnus)


Bewertung
0 lesenswert
nicht lesenswert
Jörg W. schrieb:
> Solange der TE nicht mit paar Zeilen Details mehr rausrückt, ist ihm
> nicht zu helfen.

Vielleicht hat er ja genug Hilfe bekommen. Er hatte ja nur gefragt, was 
an dem Makro falsch ist. Und es wurde geklärt, dass es an dem gar nicht 
liegt.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Bewertung
0 lesenswert
nicht lesenswert
Dann wäre es zumindest höflich, sich mit dieser Erkenntnis nochmal im 
Thread zu verewigen.

von Yalu X. (yalu) (Moderator)


Bewertung
0 lesenswert
nicht 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:

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

Clang:

test.c:15:24: error: initializer element is not a compile-time constant
float samplesPerWave = SAMPLINGRATE / toneFreq;
                       ^~~~~~~~~~~~~~~~~~~~~~~
test.c:5:22: note: expanded from macro 'SAMPLINGRATE'
#define SAMPLINGRATE 22050
                     ^

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Bewertung
0 lesenswert
nicht lesenswert
Yalu X. schrieb:
> Die Clang-Meldung
> ist also insgesamt treffender.

Auf jeden Fall.

Beitrag #6272010 wurde von einem Moderator gelöscht.
Beitrag #6272128 wurde von einem Moderator gelöscht.
von W3ll S. (w3llschmidt)


Bewertung
0 lesenswert
nicht 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:
//sub.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define SAMPLINGRATE 22050

  int zahl = 5;
  char string_array[100];

  float toneFreq = 1.f;
  float samplesPerWave = SAMPLINGRATE / toneFreq;

void a_task() {

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

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

Wobei, das funktioniert:
//sub.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define SAMPLINGRATE 22050

  int zahl = 5;
  char string_array[100];

void a_task() {

  strcpy(string_array, "Hallo");

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

}
5
22050.000000
Hallo

Danke für die rege Teilnahme :)

: Bearbeitet durch User
von Rolf M. (rmagnus)


Bewertung
0 lesenswert
nicht lesenswert
W3ll S. schrieb:
> float toneFreq = 1.f;
>   float samplesPerWave = SAMPLINGRATE / toneFreq;

Meine Glaskugel hatte recht. samplesPerWave darf nur mit Konstanten 
initialisiert werden. toneFreq ist aber eine Variable. Daher der Fehler.

W3ll S. schrieb:
> Wobei, das funktioniert:

Ja, lokale Variablen können auch mit nicht-Konstanten initialisiert 
werden.

von W3ll S. (w3llschmidt)


Bewertung
0 lesenswert
nicht lesenswert
Rolf M. schrieb:
> Meine Glaskugel hatte recht. samplesPerWave darf nur mit Konstanten
> initialisiert werden. toneFreq ist aber eine Variable. Daher der Fehler.

So einfach wa :D

const float toneFreq = 1.f;
float samplesPerWave = SAMPLINGRATE / toneFreq;

Wo kann ich das mal nachlesen?

: Bearbeitet durch User
Beitrag #6272790 wurde von einem Moderator gelöscht.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.