2016-05-13 9 views
-3

Ich weiß, dass Makros in C wie:Wie beeinflussen Makros in eingebettetem C Speicher?

#define VARNULL (u8)0 

nicht diese VARNULL im RAM speichert, aber natürlich wird die Codegröße im FLASH erhöhen.

Aber was ist, wenn ich ein mehrzeiliges Makro haben, wie:

#define CALL_FUNCS(x) \ 
do { \ 
    func1(x); \ 
    func2(x); \ 
    func3(x); \ 
} while (0) 

Mit dem Wissen, dass func1, func2 und func3 sind Funktionen aus verschiedenen .c Dateien. Bedeutet dies, dass diese Funktionen im RAM gespeichert werden? Und natürlich im FLASH (der Code).

Bitte korrigieren Sie mich, wenn ich falsch liege?

+3

Makros beeinflussen die Laufzeit nicht, sie beeinflussen den Code vor der Kompilierung. –

+0

Eine Frage pro Frage bitte. –

+1

Wenn nicht verwendet, wird 'VARNULL' nicht gespeichert.Wenn Sie 'VARNULL' verwenden, sieht der Compiler den Code so, als ob Sie' (u8) 0' geschrieben hätten, und er wird diese Null sinnvoll verwenden. Mit 'CALL_FUNCS', wenn Sie es nicht verwenden, geht nichts in das Programm. Wenn Sie es aufrufen, werden an dieser Stelle im Code drei aufeinanderfolgende Funktionsaufrufe generiert, so als hätten Sie sie aus der Ferne geschrieben. Wenn Sie ein debugbares Image haben (wahrscheinlich nicht in einem eingebetteten System), dann erscheint eine 'const'-Variable in der Symboltabelle und kann das Debuggen erleichtern; Ein Makro wird nicht aufgezeichnet, daher ist es schwieriger zu debuggen. –

Antwort

1

Makros und alle anderen Direktiven mit dem Präfix # werden vor der Kompilierung durch den Preprozessor verarbeitet. Sie generieren keinen Code, sondern erzeugen Quellcode, der dann vom Compiler verarbeitet wird, als hätten Sie den Code direkt eingegeben. So in Ihrem Beispiel des Code:

int main() 
{ 
    CALL_FUNCS(2) ; 
} 

Ergebnisse in dem generierten folgenden Quellcode:

int main() 
{ 
    do { \ 
     func1(2); 
     func2(2); 
     func3(2); 
    } while (0) ; 
} 

So einfach ist das. Wenn Sie das Makro nie aufrufen, erzeugt es genau keinen Code. Wenn Sie es mehrmals aufrufen, wird Code mehrmals generiert. Es gibt nichts schlaues geht auf das Makro ist nur ein textueller Ersatz generiert vor Compilation; Was der Compiler damit macht, hängt vollständig davon ab, zu was das Makro expandiert und nicht, dass es ein Makro ist - der Compiler sieht nur den generierten Code, nicht die Makrodefinition.

In Bezug auf const vs #define, ein Literal-Konstante Makro ist auch jyst ein Ersatztext und wird in den Code als Literal-Konstante platziert werden. A const auf der anderen Seite ist eine Variable. Der Compiler kann einfach eine Literalkonstante einfügen, in der weniger Code erzeugt wird, der die Konstante aus dem Speicher holt, in C++, die für einfache Typen garantiert ist, und es wäre für einen C-Compiler ungewöhnlich, sich nicht auf die gleiche Weise zu verhalten. Da es sich jedoch um eine Variable handelt, können Sie deren Adresse verwenden. Wenn Ihr Code die Adresse const annimmt, muss der const Speicherplatz haben. Ob der Speicher in RAM oder ROM ist, hängt von der Konfiguration des Compilers und des Linkers ab - Sie sollten die Dokumentation der Toolchain lesen, um zu erfahren, wie dieser Speicher gehandhabt wird.

Ein Vorteil der Verwendung eines const ist, dass const-Variablen im Gegensatz zu Makros starke Typisierung und Umfang haben.

4

Sie sagen, dass "natürlich" die Makros im Flash-Speicher auf Ihrem Zielgerät "gespeichert" werden, aber das stimmt nicht.

Die Makros existieren im Quellcode nur; Sie werden während der Kompilierung durch ihre definierten Werte ersetzt. Das Programm im Flash-Speicher wird sie nicht sinnvoll enthalten.