Makro zum Testen, ob ein Integer-Typ vorzeichenbehaftet oder vorzeichenlos ist

Lesezeit: 3 Minuten

Benutzer-Avatar
botismarius

Wie würden Sie (in C/C++) ein Makro schreiben, das testet, ob ein Integer-Typ (als Parameter angegeben) signiert oder unsigniert ist?


      #define is_this_type_signed (my_type) ...

  • C und C++ sind zwei verschiedene, aber verwandte Sprachen. Sie sollten dies im Hinterkopf behalten – Makros sind eine großartige Lösung in C, aber sie sind gefährlich und in C++ meistens unnötig. Makros schließen die Typprüfung in C++ komplett kurz, nur für den Anfang.

    – Onorio Catenacci

    15. September 2008 um 17:21 Uhr

  • Es gibt bestimmte Dinge, die Sie ohne Makros nicht tun können. Auf jeden Fall ist etwas C/C++-Code erforderlich, wenn Sie etwas Ähnliches in einer C++-Vorlage tun möchten.

    – Botismarius

    15. September 2008 um 17:23 Uhr

  • Können Sie bitte erklären, welche “bestimmten Dinge” ohne Makros nicht möglich sind?

    – Billy ONeal

    12. Oktober 2010 um 17:52 Uhr

Benutzer-Avatar
ChrisN

Verwenden Sie in C++ std::numeric_limits<type>::is_signed.

#include <limits>
std::numeric_limits<int>::is_signed  - returns true
std::numeric_limits<unsigned int>::is_signed  - returns false

Sehen https://en.cppreference.com/w/cpp/types/numeric_limits/is_signed.

  • Technisch gesehen kein “Makro” wie gewünscht, aber sicherlich die Standardmethode für einen eingebauten Typ.

    – Patrick Johnmeyer

    15. September 2008 um 17:57 Uhr

  • Einverstanden, aber Makros sollten in C++ IMO so weit wie möglich vermieden werden.

    – ChrisN

    15. September 2008 um 18:30 Uhr

  • Für modernes C++ (C++11 und höher) sollte dies die akzeptierte Antwort sein. Je nachdem wie es dann gebraucht wird constexpr und SFINAE (oder Konzepte in C ++ 20) können verwendet werden, um Entscheidungen zur Kompilierungszeit usw. zu treffen.

    – Krog

    7. September 2021 um 6:51 Uhr


Wenn Sie ein einfaches Makro möchten, sollte dies den Zweck erfüllen:

#define is_type_signed(my_type) (((my_type)-1) < 0)

  • Diese Antwort hat eine unitialisierte Variable; dies funktioniert möglicherweise nicht immer. Muss geändert werden in: #define is_type_signed(my_type) (((my_type(0))-1) < 0)

    – Patrick Johnmeyer

    15. September 2008 um 18:07 Uhr

  • Patrick J: In C++ funktioniert das Original aufgrund der Standardinitialisierung einwandfrei. In C hast du aber recht.

    – Branan

    18. September 2008 um 16:47 Uhr

  • Wie kann es eine nicht initialisierte Variable geben, wenn die einzigen Variablen die Temporäre 0 und -1 sind?

    – Greg Rogers

    18. September 2008 um 19:53 Uhr

  • Wäre schön, wenn es eine Lösung gäbe, die bei gcc (7.4) Fehler nicht den folgenden Fehler ausgibt: Vergleich von vorzeichenlosem Ausdruck < 0 ist immer falsch [-Werror=type-limits]

    – Aris Koning

    30. Juli 2019 um 13:45 Uhr

Wenn Sie ein Makro möchten, sollte dies den Zweck erfüllen:

#define IS_SIGNED( T ) (((T)-1)<0)

Geben Sie im Grunde -1 auf Ihren Typ um und prüfen Sie, ob es immer noch -1 ist. In C++ braucht man kein Makro. Gerade #include <limits> und:

bool my_type_is_signed = std::numeric_limits<my_type>::is_signed;

Ihre Anforderung ist nicht gerade die beste, aber wenn Sie eine Definition zusammenhacken möchten, könnte eine Option sein:

#define is_numeric_type_signed(typ) ( (((typ)0 - (typ)1)<(typ)0) && (((typ)0 - (typ)1) < (typ)1) )

Dies wird jedoch nicht berücksichtigt Hübsch oder auf irgendeine Weise tragbar.

Genau das gleiche habe ich mich heute auch schon gefragt. Folgendes scheint zu funktionieren:

#define is_signed

Ich habe getestet mit:

#include <stdio.h>

#define is_signed
#define psigned

int
main(void)
{
    psigned( int );
    psigned( unsigned int );
}

was druckt:

int is signed
unsigned int is unsigned

Benutzer-Avatar
Greg Rogers

In C++ können Sie Folgendes tun:


bool is_signed = std::numeric_limits<typeof(some_integer_variable)>::is_signed;

numeric_limits ist im Header definiert.

Benutzer-Avatar
Bronek

Obwohl typeof ist derzeit kein legales C++, Sie können stattdessen die Vorlagenableitung verwenden. Siehe Beispielcode unten:

#include <iostream>
#include <limits>

template <typename T>
bool is_signed(const T& t)
{
  return std::numeric_limits<T>::is_signed;
}

int main()
{
  std::cout << 
    is_signed(1) << " " << 
    is_signed((unsigned char) 0) << " " << 
    is_signed((signed char) 0) << std::endl;
}

Dieser Code wird gedruckt

  1 0 1

1226830cookie-checkMakro zum Testen, ob ein Integer-Typ vorzeichenbehaftet oder vorzeichenlos ist

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

Privacy policy