mit einer absoluten Zeigeradresse als Template-Argument

9

Ich habe eine Template-Klasse, die als erstes Template-Argument einen foo * -Zeiger verwendet. Ich möchte eines davon mit einem foo instanziieren, das sich an einer absoluten Adresse befindet:

%Vor%

Weiß jemand, ob es möglich ist, ohne auf den Linker zurückzugreifen und FOO_ADDR mit externer Verknüpfung zu definieren?

Dies ist mit dem Keil ARM C / C ++ Compiler Version V5.06 Update 1 (Build 61), ich habe versucht, den C ++ 11-Modus einzuschalten, aber (abgesehen davon, eine Menge neuer Fehler in die System-Header zu werfen) Es hat das Verhalten nicht verändert.

Update: Hier ist die vorgeschlagene Lösung (mit dem echten Code dieses Mal) mit int casts

%Vor%

Es ist ziemlich hässlich, aber es funktioniert. Es würde mich interessieren zu hören, ob jemand es verbessern kann?

    
Charlie Skilbeck 18.05.2016, 15:26
quelle

4 Antworten

5

Die Deklaration bar<(foo*)0x80103400> myFoo; ist schlecht formatiert, weil nicht-type Template-Argumente ein konstanter Ausdruck aus [temp.arg.nontype]:

sein müssen
  

Ein Template-Argument für einen Template-Parameter vom Typ soll ein konvertierter konstanter Ausdruck (5.20) vom Typ des Template-Parameters .

Und das Argument, das Sie übergeben, ist nicht von [expr.const]:

  

Ein Bedingungsausdruck e ist ein Kernkonstantenausdruck, es sei denn, die Auswertung von e folgt den Regeln des   abstrakte Maschine (1.9), würde einen der folgenden Ausdrücke auswerten:
  - [...]
  - a reinterpret_cast (5.2.10);   - [...]

Die Deklaration bar<(foo*)0> huh funktioniert, da sie keine Umwandlung beinhaltet, sie ist einfach ein Null-Zeiger vom Typ foo* ( 0 ist speziell) und ist daher ein gültiger konstanter Ausdruck.

Sie können die Adresse stattdessen einfach als nicht typspezifischen Parameter übergeben:

%Vor%

Das ist machbar.

    
Barry 18.05.2016, 15:46
quelle
0

Aus dem C ++ 11 Standard (Hervorhebung von mir):

  

14.3.2 Template-Nicht-Typ-Argumente

     

1 Ein Template-Argument für einen Nicht-Template Template-Parameter muss einer der folgenden sein:

     

- für einen nicht-type Template-Parameter vom Integral- oder Enumerationstyp ein konvertierter konstanter Ausdruck (5.19) vom Typ des Template-Parameters ; oder

     

- der Name eines nicht-type Template-Parameters ; oder

     

- ein konstanter Ausdruck (5.19) , der die Adresse eines Objekts mit statischer Speicherdauer und externer oder interner Verknüpfung oder eine Funktion mit externer oder interner Verknüpfung bezeichnet, einschließlich Funktionsvorlagen und Funktion Template-IDs , aber nicht-statische Klassenmitglieder ausgenommen, ausgedrückt (ignorieren Klammern) als & ID-Ausdruck , außer dass die & weggelassen werden kann, wenn der Name auf a verweist Funktion oder Array und soll entfallen, wenn der entsprechende Template-Parameter eine Referenz ist; oder

     

- ein konstanter Ausdruck, der zu einem Nullzeigerwert (4.10) führt; oder

Beim Kompilieren mit g++ -Wall erhalte ich den folgenden Fehler:

%Vor%

Es scheint, dass der Compiler erkennen kann, dass 0x80103400 ist nicht die Adresse einer Variablen, es ist nur ein konstanter Ausdruck.

    
R Sahu 18.05.2016 15:46
quelle
0

Haben Sie versucht, die Zeigeradresse auf und von uintptr_t zu werfen, was eine vorzeichenlose Ganzzahl ist, die einen Zeigerwert halten kann? Der Typ ist in einem Standard-Header <cstdint> definiert, ist jedoch nur optional. Wenn es in Ihrer Version von C ++ nicht existiert, versuchen Sie stattdessen size_t .

Ein vollständiges Beispiel würde dann wie folgt aussehen:

%Vor%

Der offensichtliche Nachteil besteht darin, dass es beim Template-Parameter keine Typisierung gibt. Sie übergeben einen Wert, der sich hoffentlich auf foo -Objekt bezieht und nicht auf ein anderes.

Ganz zu schweigen davon, dass wir in der undefinierten Verhaltenswelt sind, was den Standard betrifft ...

Sie scheinen mit der Zeile

kompilieren zu können %Vor%

mit mindestens einigen Compilern ( Ссылка )

Wenn Ihr Compiler das Casting im Kontext von constexpr ablehnt, wie es schlecht formuliert ist (gemäß Barrys Kommentar), können Sie es als reguläre static const Variable definieren:

%Vor%

Weniger ideal, aber löst dieses Problem hoffentlich.

    
CygnusX1 18.05.2016 15:37
quelle
-2

Erstens, verwende keine C-Style-Modelle. Es macht nicht explizit, was ist.

Zweitens werden Sie feststellen, dass Sie, um eine beliebige Zahl in einen Zeiger zu werfen, reinterpret_cast verwenden müssen. Diese Art von Cast ist in constexpr-Ausdrücken nicht erlaubt.

Da Vorlagenparameter nur mit konstanten Ausdrücken möglich sind, ist eine beliebige Zahl als Zeiger nicht möglich.

Der Fall, in dem 0 möglich ist, ist, weil 0 in nullptr umwandelbar ist, was ein konstanter Ausdruck ist.

    
Guillaume Racicot 18.05.2016 15:46
quelle

Tags und Links