Ist max(a,b) in stdlib.h definiert oder nicht?

Lesezeit: 5 Minuten

Ich verwende zwei Computer mit jeweils einer anderen Version von Visual Studio. Auf dem Computer von Visual Studio 2008 wird mein Code kompiliert. Auf dem Visual 2010-Computer wird mein Code nicht kompiliert, weil ich das Makro verwende max(a,b) was meines Wissens in stdlib.h definiert ist. Ich kann nicht einfach definieren max(a,b) weil es eine Neudefinition auf dem Visual 2008-Computer sein wird. Aber wenn ich nicht definiere max(a,b) Mein Code lässt sich auf dem Visual 2010-Computer nicht kompilieren.

Irgendeine Lösungsmöglichkeit?

  • Abgesehen von den in der akzeptierten Antwort besprochenen Portabilitätsproblemen bin ich neugierig, warum Sie Probleme beim Verschieben von Code mithilfe von haben max() Makro von VS2008 bis VS2010. max() ist in VS2010 definiert stdlib.h genauso wie in VS2008 (es gibt Optionen, die die Definition ausschalten, aber sie sind in beiden Compilern gleich). Mit anderen Worten, es gibt mehr als nur den Wechsel von VS2008 zu VS2010 (und das max() darin definiert werden stdlib.h nicht standardkonform ist), die dieses Problem bei Ihnen verursacht hat.

    – Michael Burr

    22. November 2010 um 20:06 Uhr

  • Auf meinem Visual C definiert die stdlib.h __min und __max.

    – Kalmarius

    26. Mai 2014 um 15:39 Uhr


  • stackoverflow.com/questions/3437404/min-and-max-in-c

    – Ciro Santilli Путлер Капут 六四事

    2. November 2016 um 7:00 Uhr

  • In Visual Studio 2015 sind min und max noch in stdlib.h definiert …

    – Ruben

    28. November 2016 um 12:06 Uhr

Benutzer-Avatar
R.. GitHub HÖREN SIE AUF, ICE ZU HELFEN

Jede C-Bibliothek, die ein Makro mit dem Namen definiert max in seinen Standard-Headern ist jenseits aller Vorstellungskraft gebrochen. Glücklicherweise gibt es eine einfache Problemumgehung, wenn Sie solche Plattformen unterstützen müssen #undef max (und alle anderen problematischen Makros, die es definiert) nach dem Einfügen der Systemheader und vor Ihren eigenen Headern/Code.

Beachten Sie, dass alle anderen sagen, dass Sie Ihre Definition einpacken sollen #ifndef max ... #endif. Das ist nicht eine gute Idee. Definieren max in einem Systemheader ist ein Hinweis darauf, dass der Implementierer inkompetent war, und es ist möglich, dass bestimmte Versionen der Umgebung dies getan haben falsch Makros (zum Beispiel solche, die Argumente nicht richtig mit Klammern schützen, aber ich habe sogar eine gesehen max Makro, das nicht richtig ausgeführt wurde min Anstatt von max mindestens einmal in meinem Leben!). Benutz einfach #undef und sicher sein.

Warum es so kaputt ist stdlib.h definieren max, ist der C-Standard sehr genau darin, welche Namen für die Anwendung reserviert sind und welche Namen für Standardfunktionen und/oder die interne Verwendung durch die Implementierung reserviert sind. Dafür gibt es sehr gute Gründe. Das Definieren von Makronamen in Systemkopfzeilen, die mit im Anwendungsprogramm verwendeten Variablen-/Funktionsnamen kollidieren könnten, ist gefährlich. Im besten Fall führt dies zu Kompilierzeitfehlern mit offensichtlicher Ursache, aber in anderen Fällen kann es zu sehr seltsamem Verhalten kommen, das schwer zu debuggen ist. Auf jeden Fall macht es das Schreiben von portablem Code sehr schwierig, da man nie weiß, welche Namen bereits von der Bibliothek übernommen werden.

  • Meine Antwort wurde entfernt: Ihre ist derzeit am besten geeignet.

    – San Jacinto

    20. November 2010 um 17:31 Uhr

  • @R .. Danke, aber könnten Sie bitte erklären, warum eine C-Bibliothek, die max definiert, jenseits aller Vorstellungskraft kaputt ist?

    – Schlange

    20. November 2010 um 17:34 Uhr

  • Ihre Kommentare zum Warum <stdlib.h> nicht definieren soll max sind bis zu einem bestimmten Punkt gültig. Wenn der Benutzer explizit zusätzliche Definitionen anfordert, die die Implementierung bereitstellt (z. B. durch Definieren von __EXTENSIONS__ (inoffiziell) bzw _POSIX_C_SOURCE (offiziell)), dann ist es zulässig für <stdlib.h> um zusätzliche Definitionen bereitzustellen. Und auf vielen Plattformen sind die Erweiterungen möglicherweise standardmäßig aktiviert und werden nur durch Anforderung des „standardkonformen Modus“ deaktiviert.

    – Jonathan Leffler

    20. November 2010 um 18:12 Uhr

  • @Jonathan: Es stimmt jedoch auch, dass das Definieren unerwarteter Makros für Programmierer schwieriger ist als das Definieren unerwarteter Funktionen. Die Compilerfehler (falls vorhanden) machen wahrscheinlich weniger Sinn.

    – Steve Jessop

    20. November 2010 um 21:23 Uhr

  • Dennoch, das Beispiel hier (max) ist sehr extrem. Ich würde das nur ein oder zwei Ebenen der Schlechtigkeit unter Putten setzen #define i _Complex_I in einer Standard-Header-Datei. Beachten Sie auch, dass in diesem Fall die einzige Möglichkeit zum Deaktivieren der Erweiterung darin besteht, ein anderes Makro in dem für die Anwendung reservierten Namespace zu verwenden (#define NOMINMAX), was jede Hoffnung auf eine konforme Implementierung ausschließt.

    – R.. GitHub HÖR AUF, EIS ZU HELFEN

    20. November 2010 um 21:23 Uhr

Also zur Beantwortung deiner Hauptfrage:

Ist max(a,b) in stdlib.h definiert oder nicht?

Nein, ist es nicht, es ist in windef.h um Zeile 187 herum definiert:

#ifndef NOMINMAX

#ifndef max
#define max(a,b)            (((a) > (b)) ? (a) : (b))
#endif

#ifndef min
#define min(a,b)            (((a) < (b)) ? (a) : (b))
#endif

#endif  /* NOMINMAX */

Benutzer-Avatar
John Ledbetter

Schützen Sie es mit einem #ifndef.

#ifndef max
    #define max(a,b) ((a) > (b) ? (a) : (b))
#endif

Beachten Sie, dass die obige Version nicht so sicher ist wie eine Inline-Funktion, z max(a++,b--) führt zu unerwarteten Ergebnissen.

  • Ihr Makro gibt das Minimum der beiden Zahlen an. Sollte sein (a) > (b)

    – Halex

    26. März 2015 um 19:40 Uhr

  • überrascht, dass es in den letzten 5 Jahren niemandem aufgefallen ist. Fest!

    – John Ledbetter

    26. März 2015 um 19:59 Uhr

Sie können die Bedingungskompilierung verwenden:

#ifndef max
  #define max(a,b) ...
#endif

In Visual C++, wenn Sie #define NOMINMAX Bevor Sie die Standardheader einfügen, erhalten Sie kein Makro max oder min.

  • Das ist noch ein weiterer Fehler. Wenn sie es geschafft hätten _NOMINMAX stattdessen wäre es konform, aber NOMINMAX ist für die Anwendung reserviert, und es ist nicht konform, dass die Header der Standardbibliothek sie für ihre eigenen Zwecke verwenden.

    – R.. GitHub HÖR AUF, EIS ZU HELFEN

    20. November 2010 um 17:42 Uhr

  • Das ist noch ein weiterer Fehler. Wenn sie es geschafft hätten _NOMINMAX stattdessen wäre es konform, aber NOMINMAX ist für die Anwendung reserviert, und es ist nicht konform, dass die Header der Standardbibliothek sie für ihre eigenen Zwecke verwenden.

    – R.. GitHub HÖR AUF, EIS ZU HELFEN

    20. November 2010 um 17:42 Uhr

1341790cookie-checkIst max(a,b) in stdlib.h definiert oder nicht?

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

Privacy policy