Ändern eines Makros zur Laufzeit in C

Lesezeit: 5 Minuten

Benutzer-Avatar
Leuchtturm

Ich habe ein Makro definiert. Aber ich muss diesen Wert zur Laufzeit abhängig von einer Bedingung ändern. Wie kann ich das umsetzen?

  • Makros durchlaufen den Präprozessor. Sie können während der Laufzeit nicht geändert werden. Ist dies eine Makrokonstante oder ein Funktionsmakro, das ein Argument akzeptiert?

    Benutzer195488

    27. September 2011 um 16:58 Uhr


  • Übrigens, diese Frage ist gut, also können wir sie auf Stackoverflow mit “nein” beantworten.

    – Prof. Falken

    27. September 2011 um 17:03 Uhr


  • Könnten Sie bitte ein Beispiel für Ihr Makro geben – es scheint mir, dass Sie nicht wirklich ein runtime-updateable-macro benötigen, was keinen Sinn ergibt – sondern ein Makro mit einem oder mehreren zusätzlichen Parametern. Oder vielleicht überarbeiten Sie Ihren Code trotzdem ..

    – rudolf_franek

    27. September 2011 um 17:14 Uhr

  • # definiere SIZE 100 und in dem Code, den du verwenden möchtest, sollte es in einigen Fällen 50 sein. Was wird dann mein Schritt sein? Weil ich eine Menüliste in Abhängigkeit von der GRÖSSE erstellen möchte. if(something) then create 50 menu else create SIZE menu Derzeit habe ich nur eine Variable erstellt und den Variablenwert abhängig von der Bedingung geändert, während er zuvor vom Marco aktualisiert wurde.

    – Leuchtturm

    27. September 2011 um 17:19 Uhr


  • @lighthouse, Variablen sind dann der richtige Weg.

    – Prof. Falken

    27. September 2011 um 20:08 Uhr

Benutzer-Avatar
fbrereto

Makros werden vom Präprozessor durch ihren Wert ersetzt, bevor Ihre Quelldatei überhaupt kompiliert wird. Es gibt keine Möglichkeit, den Wert des Makros zur Laufzeit zu ändern.

Wenn Sie etwas mehr über das Ziel erklären könnten, das Sie erreichen möchten, gibt es zweifellos eine andere Möglichkeit, Ihr Problem zu lösen, die keine Makros enthält.

  • Was ist, wenn das Makro einer Funktion zugewiesen wird, die über die Logik verfügt, um den gewünschten Wert zu erhalten, und zurückgibt? Wäre das Makro dann nicht in der Lage, einen dynamischen Wert zurückzugeben?

    – Hartes S.

    30. Januar 2019 um 5:24 Uhr

  • @HarshS. Wenn das Makro in eine Funktion aufgelöst wird, ersetzt der Präprozessor das Makro durch den Namen der Funktion, bevor die C++-Datei kompiliert wird. Das Makro selbst wird dabei nicht “dynamisch”. Vielmehr ist das Ding, in das das Makro aufgelöst wird, ein Ding, das einen Laufzeitwert zurückgibt.

    – fbrereto

    31. Januar 2019 um 19:50 Uhr

Benutzer-Avatar
Steve Jessop

Sie können das Makro selbst nicht ändern, dh worauf es erweitert wird, aber möglicherweise können Sie den Wert von an ändern Ausdruck unter Einbeziehung des Makros. Für ein sehr dummes Beispiel:

#include <stdio.h>

#define UNCHANGEABLE_VALUE 5
#define CHANGEABLE_VALUE foo

int foo = 5;

int main() {
    printf("%d %d\n", UNCHANGEABLE_VALUE, CHANGEABLE_VALUE);
    CHANGEABLE_VALUE = 10;
    printf("%d %d\n", UNCHANGEABLE_VALUE, CHANGEABLE_VALUE);
}

Die Antwort auf Ihre Frage hängt also davon ab, welche Auswirkungen Ihre Änderung auf den Code haben soll, der das Makro verwendet.

Na sicher 5 ist eine Kompilierzeitkonstante, während foo ist nicht, also funktioniert dies nicht, wenn Sie es verwenden möchten CHANGEABLE_VALUE Als ein case Etikett oder was auch immer.

Denken Sie daran, dass es zwei (eigentlich mehr) Phasen der Übersetzung der C-Quelle gibt. Im ersten (von den beiden, die uns wichtig sind) werden Makros erweitert. Wenn das alles erledigt ist, wird das Programm “syntaktisch und semantisch analysiert”, wie es in 5.1.1.2/2 heißt. Diese beiden Schritte werden oft als „Vorverarbeitung“ und „Kompilierung“ bezeichnet (obwohl mehrdeutig oft auch der gesamte Übersetzungsprozess als „Kompilierung“ bezeichnet wird). Sie können sogar durch separate Programme implementiert werden, wobei der “Compiler” den “Präprozessor” nach Bedarf ausführt, bevor er irgendetwas anderes tut. Die Laufzeit ist also viel, viel zu spät, um zu versuchen, zurückzugehen und zu ändern, worauf ein Makro erweitert wird.

  • hmm .. diese Antwort besagt, dass Sie ein Makro als Fallbezeichnung verwenden können: stackoverflow.com/questions/1674032/static-const-vs-define-in-c/…

    Benutzer195488

    27. September 2011 um 17:34 Uhr

  • @0A0D: Es heißt: “Sie können kein const int-Objekt als Case-Label verwenden (während ein Makro funktioniert)”. Das soll das nicht bedeuten irgendein Makro ist eine Bezeichnung für Rechtsfälle, oder dass Sie mit einem Makro auf magische Weise Dinge in Fallbezeichnungen verwenden können, die Sie sonst nicht könnten. AndreyT vergleicht const int Objekte mit Makros als Integer-Literale definiert. case UNCHANGEABLE_VALUE: ist in Ordnung, case CHANGEABLE_VALUE: ist nicht.

    – Steve Jessop

    27. September 2011 um 17:43 Uhr


Du kannst nicht. Makros werden um die erweitert Präprozessor, was noch vor dem Kompilieren des Codes geschieht. Es ist ein rein textlicher Ersatz.

Wenn Sie zur Laufzeit etwas ändern müssen, ersetzen Sie einfach Ihr Makro durch einen echten Funktionsaufruf.

  • Könnten Sie bitte ein einfaches Beispiel geben, wie Sie es durch einen Funktionsaufruf ersetzen können?

    – utvecklare

    11. September 2013 um 11:25 Uhr

Du kannst nicht.

Da ein Makro vom Präprozessor vor der Kompilierung selbst aufgelöst wird, wird sein Inhalt direkt dorthin kopiert, wo Sie ihn verwenden.

Sie können weiterhin Parameter verwenden, um je nach Wunsch eine bedingte Anweisung einzufügen, oder eine im Aufrufbereich zugängliche Variable verwenden.

Wenn Sie einen einzelnen Wert ändern möchten, verwenden Sie besser eine globale Bereichsvariable, auch wenn von einem solchen Verhalten abgeraten wird. (wie die intensive Verwendung von Makro)

Je nachdem, was Sie tun möchten, können Sie dies auf verschiedene Arten tun.

Globale Variable statt Makro

// someincludefile.h
extern static int foo;

// someincludefile.c
static int foo = 5;

// someotherfile.c
#include "someincludefile.h"
printf("%d\n", foo); // >> 5
foo = -5;
printf("%d\n", foo); // >> -5

Bedingung, die Sie umschalten können

// someincludefile.h
extern static int condition;
#define FOO1 (5)
#define FOO2 (-5)
#define FOO (condition ? (FOO1) : (FOO2))

// someincludefile.c
static int condition = 1;

// someotherfile.c
#include "someincludefile.h"
printf("%d\n", FOO); // >> 5
condition = 0;
printf("%d\n", FOO); // >> -5

Bedingung, die lokal und dynamisch ausgewertet wird

// someincludefile.h
#define CONDITION (bar >= 0)
#define FOO1 (5)
#define FOO2 (-5)
#define FOO ((CONDITION) ? (FOO1) : (FOO2))

// someotherfile.c
#include "someincludefile.h"
int bar = 1;
printf("%d\n", FOO); // >> 5
bar = -1;
printf("%d\n", FOO); // >> -5

In letzterem wird die BEDINGUNG so ausgewertet, als wäre ihr Code in Ihrem lokalen Gültigkeitsbereich, sodass Sie darin lokale Variablen und/oder Parameter verwenden können, aber Sie können auch globale Variablen verwenden, wenn Sie möchten.

1383820cookie-checkÄndern eines Makros zur Laufzeit in C

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy