c++ - wurden - makros aktivieren excel 2017




Über die Abhängigkeit von Makros (9)

Die Frage ist, gibt es Probleme, die ohne Makros nicht gelöst werden können?

Nein.

Sind Makros letztendlich eine gute / zurück Übung? Wann sollte ich ein Makro verwenden?

In Sprachen, die das inline Schlüsselwort nicht unterstützen oder nicht honorieren, sind Makros eine großartige Möglichkeit, Code wiederzuverwenden, gleichzeitig aber den Overhead eines Funktionsaufrufs in jedem Code zu vermeiden, der ausreichend durchgeschleift ist, um einen riesigen Code zu erstellen Unterschied.

Ihre Gerüchte über Code, der mit Makros übersät ist, sind wahrscheinlich gerechtfertigt. Es gibt tatsächlich schwer zu debuggen und in einigen Fällen zu lesen. Aber sie kommen in der sehr kleinen Anzahl von Fällen nützlich, in denen eine Optimierung wie diese wirklich gerechtfertigt ist.

Beachten Sie, dass C ab C99 jetzt explizite Inline-Funktionen mit dem inline Schlüsselwort ausführen kann, was die Notwendigkeit von Makros reduziert und sogar Vorteile gegenüber der Verwendung von Makros hat .

Ich fühle, dass jedes Mal, wenn ich ein C- oder C ++ - Programm lese, diese Hälfte oder mehr nur Makros sind. Ich verstehe, dass Makros cool sein können, aber sie sind schwer zu verfolgen, zu debuggen, etc. Nicht zu erwähnen, dass die meisten Programmiersprachen nicht einmal etwas wie Makros definieren (obwohl Perl6 etwas von der Art haben wird).

Ich persönlich habe immer einen Weg gefunden, meinen Code zu schreiben, ohne Makros zu verwenden, sei es mit Templates, Mehrfachvererbung usw. Ich habe sogar das Gefühl, dass ich kein guter Programmierer bin, weil alle Profis Makros verwenden und ich versuche, sie zu vermeiden so wie ich kann.

Die Frage ist, gibt es Probleme, die ohne Makros nicht gelöst werden können? Sind Makros letztlich eine gute / schlechte Übung? Wann sollte ich ein Makro verwenden?


Das Debug-Verhalten kann mit konstanten Flags oder Debug-Funktionen gesteuert werden. Also hier ist meine Liste der unvermeidlichen:

  • Mehrfacher Einschlussschutz.
  • Makros sind die einzige Möglichkeit der Symbolbeschriftung. assert macro, kompakte Realisierung von const string & stringify (enum category value);

Beispiel:

const char* stringify(enum category value)
{
    #define c(x) case x: return #x;
    switch(value) {
        c(CIRCLE)
        c(RECTANGLE)
        c(TRIANGLE)
        default: return "UNKNOWN";
    }
    #undef c // the most important part
}

Es gibt viele Probleme, die ich ohne Makros nicht lösen kann. Zum Beispiel Serialisierung / Deserialisierung einiger Strukturen

#define STRUCT_DESCRIPTION structname(MyStruct) member(int,a) member(double,b) member(long, c)
#include "declare_serializable_struct.h" // declares struct itself and generates serialization/deserializaton code
#undef STRUCT_DESCRIPTION

(BOOST_PP_SEQUENCE kann auch verwendet werden) Ein weiteres Beispiel - das Versenden einer Nachricht mit Message Map, dh das Generieren eines Switches wie folgt:

switch(message_type)
{
case msg1: on_msg1(msg); break;
case msg2: on_msg2(msg); break;
...
}

und generieren Handler-Methodendeklarationen on_msgX (msg) zur gleichen Zeit unter Verwendung einer Nachrichtenbeschreibungstabelle ("map")

Persönlich versuche ich Makros zu vermeiden, wenn es möglich ist, aber das ist mir nicht gelungen.

Lambdas in c ++ 0x erlaubt jedoch, beliebigen Code in "user-or-library-defined langage statements" einzufügen, wie zum Beispiel foreach loops, so dass der Makrobereich einen wesentlichen Teil verliert :)


Ich denke, dass C ++ Templates und Inline-Funktionen Makros ziemlich vermeidbar machen.

Die Allgegenwärtigkeit von Makros ist wahrscheinlich auf die Tatsache zurückzuführen, dass es viele C ++ - Programmierer gibt, die früher C-Programmierer waren. Solche Leute werden wahrscheinlich Makros beherrschen (weil es manchmal wirklich die beste oder einzige Lösung in reinem C ist) und vielleicht keinen Sinn darin sehen, die komplizierteren C ++ - Funktionen zu lernen, wenn sie bereits wissen, wie man das Problem löst. Zumindest in der Open-Source-Welt gibt es viele C-Konvertierungen, so dass Sie natürlich C-Paradigmen erfüllen. Ich glaube nicht, dass du ein schlechter Programmierer bist, wenn du eine solche Funktion meidest, tun das viele Leute genauso wie GOTOs.

C (und daher C ++) ist eine extrem flexible Programmiersprache. Das ist großartig, denn jeder kann seinen eigenen Stil entwickeln und die meisten Probleme auf verschiedene Arten lösen. Dies kann jedoch auch als Problem angesehen werden. Meiner Meinung nach kein Problem, das durch die Sprache gelöst werden sollte, sondern durch die Festlegung von Konventionen.

Es gibt viele Funktionen in C ++, die sicher ignoriert werden können. Vielleicht gibt es seltsame besondere Anlässe, bei denen solch ein Feature wirklich der beste Ansatz wäre, aber in den meisten Fällen können Sie ohne leben:

  • Freund Klassen
  • Makros
  • GOTOs und mehr.

IMO, ein erfahrener C ++ - Programmierer sollte in der Lage sein, sie alle fließend zu lesen - aber ich erwarte, dass ein guter Programmierer sorgfältig darüber nachdenkt, wann und ob er eine berüchtigte Funktion verwenden soll.


Ich versuche auch, Makros zu vermeiden, aber um das Debugging zu erweitern, habe ich keine Möglichkeit gefunden, den Dateinamen, den Funktionsnamen und die Zeilennummer beim Debuggen zu drucken.

Ich habe normalerweise eine Header-Datei namens DebugLog.h mit dem folgenden Makro

#define DEBUG(debugMessage) \
   printf("%s | %s [%d] - %s\n", __FILE__, __PRETTY_FUNCTION___, debugMessage);

Mit: DEBUG ("Test") gibt etwas aus wie:

main.cpp | foo(void)[20] - Test

Sie können das Makro für C ++ und andere Debugging-Anweisungen anpassen. Es ist auch möglich, das Makro so zu modifizieren, dass die resultierende Zeichenfolge an einen Logger gesendet wird.


Ja, hier ist einer. Wenn Sie Ihrem Programm Tracing-Code hinzufügen müssen, so dass eine Konfiguration es enthält und die andere vollständig auslässt, müssen Sie Makros verwenden.

Etwas wie:

#ifdef WITH_LOGGING
    #define LOG( x ) DoLog( x )
#else
    #define LOG( x )
#endif

jetzt benutzt du es so:

LOG( L"Calling blahblahblah with " + getSomeStringHardToCompute() );

und in der Konfiguration mit WITH_LOGGING hast du diesen Code und ansonsten wird er komplett weggelassen - nicht einmal in der Binärdatei und daher

  • Es hilft anderen nicht, Ihr Programm zu analysieren
  • Sie erhalten eine kleinere Binärdatei
  • Das Programm vergeudet keine Zeit für die Protokollierung
  • Der Compiler kann besser optimierten Code erzeugen.

Makros sind natürlich auch nützlich, wenn Sie während der Vorverarbeitung Code generieren möchten. Während dies mit Vorlagen vermieden werden kann (siehe diese SO Frage und Diskussion - Sind C ++ Vorlagen nur Makros versteckt? ), Können Sie Makros verwenden, wenn es das Leben Ihrer Benutzer einfacher macht - sehen Sie, wie das 'googeltest' Projekt ( https: / /github.com/google/googletest/ ) verwendet Makros effektiv. Sie möchten offensichtlich keine Makros verwenden, um Code zu generieren, der das Debuggen erfordert, sondern Vorlagen verwenden.


Programmiersprachen-Makros sind gut für das, wofür alle Makros gut sind: Sie vermeiden es, die gleichen Dinge immer und immer wieder zu tippen. Wenn Sie also an vielen Stellen dieselben Code-Teile schreiben, warum nicht ein Makro daraus machen? Besonders wenn Sie eine Bibliothek schreiben, kann die Verwendung von Makros das Leben für jemanden erleichtern, der versucht, diese Bibliothek zu benutzen. Sehen Sie sich fast jedes GUI-Toolkit an (Qt ist ein Beispiel). Sie alle nutzen Makros ausgiebig.


Vielleicht ist es ein wenig off-topic, aber ich habe einen Beitrag darüber gelesen, wie man die Kompilierungszeit verkürzt.

Und der Autor beobachtete, dass das Einbeziehen jeder Codezeile in einer einzigen Datei mit einem Makro (ja, es ist hässlich) sowohl die Kompilierungszeit als auch die Größe um ein starkes Verhältnis verringerte (~ 70% für beide Parameter).

Irgendeine Erklärung?





macros