🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Thread View: de.comp.lang.iso-c++
14 messages
14 total messages Started by Heinz Saathoff Fri, 04 Dec 2015 10:29
anonymous namspace referenzieren?
#52482
Author: Heinz Saathoff
Date: Fri, 04 Dec 2015 10:29
33 lines
764 bytes
Hallo,

gegeben ist eine Funktion mit gleichem Namen im globalen namespace und
im anonymen namspace. Hier ein Beispiel:

   #include <iostream>

   void Func() {
      std::cout << "global Func\n";
   }

   namespace {
      void Func() {
         std::cout << "namespace Func\n";
      }

      void Foo() {
         std::cout << "Foo calls Func\n";
         Func(); // -> namespace Func
      }
   }//namespace

   int main(int argc, char *argv[])
   {
      ::Func();              // global namespace Func
      Func();                // Fehler, ambiguous call
      // unnamed::Func()     // wie ??
      Foo();                 // über 'Umweg'
   }//main

Gibt's eine Möglichkeit, aus main heraus die 'lokale' Func statt der
globalen aufzurufen?

- Heinz
Re: anonymous namspace referenzieren?
#52484
Author: =?ISO-8859-1?Q?D
Date: Fri, 04 Dec 2015 10:44
90 lines
2655 bytes
Am Freitag, 4. Dezember 2015 11:40:04 UTC+1 schrieb Heinz Saathoff:
> Hallo,
> 
> gegeben ist eine Funktion mit gleichem Namen im globalen namespace und
> im anonymen namspace. Hier ein Beispiel:
> 
>    #include <iostream>
> 
>    void Func() {
>       std::cout << "global Func\n";
>    }
> 
>    namespace {
>       void Func() {
>          std::cout << "namespace Func\n";
>       }
>    
>       void Foo() {
>          std::cout << "Foo calls Func\n";
>          Func(); // -> namespace Func
>       }
>    }//namespace
> 
>    int main(int argc, char *argv[])
>    {
>       ::Func();              // global namespace Func
>       Func();                // Fehler, ambiguous call
>       // unnamed::Func()     // wie ??
>       Foo();                 // über 'Umweg'   
>    }//main
> 
> Gibt's eine Möglichkeit, aus main heraus die 'lokale' Func statt der
> globalen aufzurufen?

Wenn du den Namen des unbenannten Namensraum kennen würdest, könntest du es tun ;-)

So gesagt, kann man es als Witz verstehen, aber was ich damit sagen will, könnte dir den Pfad zu einer möglichen Lösung deines Problems aufweisen.

Die Semantik einer Deklaration eines unbenannten Namensraums ist äquivalent zu

namespace /unique/ { /* empty body */ }
using namespace /unique/;
namespace /unique/ { /namespace-body/ }

wobei /unique/ innerhalb einer Übersetzungseinheit immer der gleiche (aber nur dem Compiler bekannte) Identifikator ist mit (seit C++11) der zusätzlichen Eigenschaft, dass alle Inhalte eines unbenannten Namensraums (inklusive ihm selbst) interne Bindung aufweisen. Wenn du also zum Ziel hast, dass du (a) den Inhalten des von dir geschaffenen Namensraums interne Bindung haben soll *und* zusätzlich qualifiziert benannt werden können soll, dann könntest du dies auf folgende Weise erreichen:

a) Deklarieren einen benannten Namensraum und
b) Deklariere seinen Inhalt so, dass er interne Bindung hat

Auf dein Beispiel angewandt:

   #include <iostream>

   void Func() {
      std::cout << "global Func\n";
   }

   namespace bibabuze { 
      static void Func() {
         std::cout << "namespace Func\n";
      }
   
      static void Foo() {
         std::cout << "Foo calls Func\n";
         Func(); // -> namespace Func
      } 
   }
   using namespace bibabuze;

   int main()
   {
      ::Func();              // global namespace Func
      Func();                // Fehler, ambiguous call 
      // unnamed::Func()     // wie ??
      ::bibabuze::Func();    // so.
      Foo();                 // über 'Umweg'  
   }

Besten Gruß aus Bremen,

Daniel Krügler 
Re: anonymous namspace referenzieren?
#52483
Author: ram@zedat.fu-ber
Date: Fri, 04 Dec 2015 16:55
4 lines
144 bytes
Heinz Saathoff <newshsaat@arcor.de> writes:
>Gibt's eine Möglichkeit, aus main heraus die 'lokale' Func statt der
>globalen aufzurufen?

  Nein.
Re: anonymous namspace referenzieren?
#52485
Author: Heinz Saathoff
Date: Sat, 05 Dec 2015 11:27
75 lines
2641 bytes
Moin,


Daniel Krügler schrieb:

>Am Freitag, 4. Dezember 2015 11:40:04 UTC+1 schrieb Heinz Saathoff:
>> Hallo,
>>
>> gegeben ist eine Funktion mit gleichem Namen im globalen namespace und
>> im anonymen namspace. Hier ein Beispiel:
>>
>>    #include <iostream>
>>
>>    void Func() {
>>       std::cout << "global Func\n";
>>    }
>>
>>    namespace {
>>       void Func() {
>>          std::cout << "namespace Func\n";
>>       }
>>
>>       void Foo() {
>>          std::cout << "Foo calls Func\n";
>>          Func(); // -> namespace Func
>>       }
>>    }//namespace
>>
>>    int main(int argc, char *argv[])
>>    {
>>       ::Func();              // global namespace Func
>>       Func();                // Fehler, ambiguous call
>>       // unnamed::Func()     // wie ??
>>       Foo();                 // über 'Umweg'
>>    }//main
>>
>> Gibt's eine Möglichkeit, aus main heraus die 'lokale' Func statt der
>> globalen aufzurufen?
>
>Wenn du den Namen des unbenannten Namensraum kennen würdest, könntest du es tun ;-)
>
>So gesagt, kann man es als Witz verstehen, aber was ich damit sagen will, könnte dir den Pfad zu einer möglichen Lösung deines Problems aufweisen.
>
>Die Semantik einer Deklaration eines unbenannten Namensraums ist äquivalent zu
>
>namespace /unique/ { /* empty body */ }
>using namespace /unique/;
>namespace /unique/ { /namespace-body/ }
>
>wobei /unique/ innerhalb einer Übersetzungseinheit immer der gleiche (aber nur dem Compiler bekannte) Identifikator ist mit (seit C++11) der zusätzlichen Eigenschaft, dass alle Inhalte eines unbenannten Namensraums (inklusive ihm selbst) interne Bindung aufweisen. Wenn du also zum Ziel hast, dass du (a) den Inhalten des von dir geschaffenen Namensraums interne Bindung haben soll *und* zusätzlich qualifiziert benannt werden können soll, dann könntest du dies auf folgende Weise erreichen:
>
>a) Deklarieren einen benannten Namensraum und
>b) Deklariere seinen Inhalt so, dass er interne Bindung hat

Ich muß sagen, dass mir diese Lösung nicht besonders gefällt.
Meine Hoffnung war, dass es einen Bezeichner mit Schlüsselwortcharakter
gibt, mit dem man den vom Compiler generierten Namen angeben kann. So
ähnlich, wie das mit dem this-pointer für Objekte der Fall ist. Also
etwa so

  namespace {
     void Func() {...}
  }

  unnamed::Func();

wobei unnamed vom Compiler durch den generierten Bezeichner ersetzt
wird.
Ich vermute mal, das es keinen Bedarf dafür gab.

BTW, ich habe bisher gerne static für file local scope verwendet, was
aber auch nur funktioniert, wenn der Name der Funktion nicht in einem
der inkludierten Header vorkommt.


- Heinz
Re: anonymous namspace referenzieren?
#52486
Author: ram@zedat.fu-ber
Date: Sun, 06 Dec 2015 01:17
6 lines
277 bytes
Heinz Saathoff <newshsaat@arcor.de> writes:
>Daniel Krügler schrieb:
>>a) Deklarieren einen benannten Namensraum und
>>b) Deklariere seinen Inhalt so, dass er interne Bindung hat
>Ich muß sagen, dass mir diese Lösung nicht besonders gefällt.

  Und was gefällt Dir daran nicht?
Re: anonymous namspace referenzieren?
#52487
Author: Udo Steinbach
Date: Sun, 06 Dec 2015 10:59
8 lines
227 bytes
> namespace {
>    void Func() {...}
> }
> unnamed::Func();

Dann müßte inline namespace das richtige sein.
--
Fahrradverkehr in Deutschland: http://radwege.udoline.de/
GPG: A245 F153 0636 6E34 E2F3  E1EB 817A B14D 3E7E 482E
Re: anonymous namspace referenzieren?
#52488
Author: Heinz Saathoff
Date: Sun, 06 Dec 2015 11:54
19 lines
644 bytes
Stefan Ram schrieb:

>Heinz Saathoff <newshsaat@arcor.de> writes:
>>Daniel Krügler schrieb:
>>>a) Deklarieren einen benannten Namensraum und
>>>b) Deklariere seinen Inhalt so, dass er interne Bindung hat
>>Ich muß sagen, dass mir diese Lösung nicht besonders gefällt.
>
>  Und was gefällt Dir daran nicht?

Das man einen benannten Namespace definiert und darin wieder static
nutzt. Eigentlich sollten die anonymous namespaces doch als Ersatz für
static dienen.
Ok, gegen das Problem des gleichen Namens hilft der Vorschlag von
Daniel.
Schöner fände ich allerdings die Nuttzung eines reservierten Bezeichners
für die anonyme namespace.


- Heinz
Re: anonymous namspace referenzieren?
#52489
Author: Christoph Kliemt
Date: Sun, 06 Dec 2015 12:38
15 lines
471 bytes
ram@zedat.fu-berlin.de (Stefan Ram) writes:

> Heinz Saathoff <newshsaat@arcor.de> writes:
>>Daniel Krügler schrieb:
>>>a) Deklarieren einen benannten Namensraum und
>>>b) Deklariere seinen Inhalt so, dass er interne Bindung hat
>>Ich muß sagen, dass mir diese Lösung nicht besonders gefällt.
>
>   Und was gefällt Dir daran nicht?

In meiner schlichten Naivität frage ich mich: Wofür braucht man sowas?


Gruss Christoph

p.s. Die Frage ist durchaus ernstgemeint!
Re: anonymous namspace referenzieren?
#52490
Author: Stefan Reuther
Date: Sun, 06 Dec 2015 12:48
49 lines
1829 bytes
Am 05.12.2015 um 11:27 schrieb Heinz Saathoff:
>> a) Deklarieren einen benannten Namensraum und
>> b) Deklariere seinen Inhalt so, dass er interne Bindung hat
>
> Ich muß sagen, dass mir diese Lösung nicht besonders gefällt.
> Meine Hoffnung war, dass es einen Bezeichner mit Schlüsselwortcharakter
> gibt, mit dem man den vom Compiler generierten Namen angeben kann.

Nur, wozu soll das am Ende gut sein? Die Grundannahme bei der Definition
der Sprache dürfte schlicht gewesen sein, dass Anonymspaces sowieso nur
in *.cpp-Dateien vorkommen, und da kann man völlig schmerzarm bei
Namenskonflikten die Funktion einfach ohne Außenwirkung umbenennen oder
in einen benannten Namespace packen.

> So ähnlich, wie das mit dem this-pointer für Objekte der Fall ist. Also
> etwa so
>
>   namespace {
>      void Func() {...}
>   }
>
>   unnamed::Func();
>
> wobei unnamed vom Compiler durch den generierten Bezeichner ersetzt
> wird.

Du kannst auch sowas
   namespace unnamed { namespace {
      void Func() { ... }
   } }
   unnamed::Func();
machen, um die Vorteile des benannten Namespaces (Funktion per
Namespace-Präfix erreichbar) und des Anonymspaces (Funktion von außen
nicht erreichbar) zu kombinieren.

> Ich vermute mal, das es keinen Bedarf dafür gab.
>
> BTW, ich habe bisher gerne static für file local scope verwendet, was
> aber auch nur funktioniert, wenn der Name der Funktion nicht in einem
> der inkludierten Header vorkommt.

Den Zusammenhang seh ich jetzt nicht. Allerdings ist 'static' meines
Wissens deprecated und erlaubt auch keine lokalen Klassen-Definitionen.
Der Anonymspace ist da einfach das modernere Sprachmittel, und die
Compiler bekommen den auch langsam halbwegs effizient auf die Reihe
(generieren also nicht mehr eine Latte externer Symbole für Funktionen
und Klassen im Anonymspace).


  Stefan
Re: anonymous namspace referenzieren?
#52491
Author: Heinz Saathoff
Date: Sun, 06 Dec 2015 17:18
60 lines
1979 bytes
Stefan Reuther schrieb:

>Am 05.12.2015 um 11:27 schrieb Heinz Saathoff:
>>> a) Deklarieren einen benannten Namensraum und
>>> b) Deklariere seinen Inhalt so, dass er interne Bindung hat
>>
>> Ich muß sagen, dass mir diese Lösung nicht besonders gefällt.
>> Meine Hoffnung war, dass es einen Bezeichner mit Schlüsselwortcharakter
>> gibt, mit dem man den vom Compiler generierten Namen angeben kann.
>
>Nur, wozu soll das am Ende gut sein? Die Grundannahme bei der Definition
>der Sprache dürfte schlicht gewesen sein, dass Anonymspaces sowieso nur
>in *.cpp-Dateien vorkommen, und da kann man völlig schmerzarm bei
>Namenskonflikten die Funktion einfach ohne Außenwirkung umbenennen oder
>in einen benannten Namespace packen.

Das ist natürlich richtig. Umbenennung ist immer eine Alternative und
manchmal geht's auch nicht anders, denn bei #defines helfen auch
namespaces nicht.


>> So ähnlich, wie das mit dem this-pointer für Objekte der Fall ist. Also
>> etwa so
>>
>>   namespace {
>>      void Func() {...}
>>   }
>>
>>   unnamed::Func();
>>
>> wobei unnamed vom Compiler durch den generierten Bezeichner ersetzt
>> wird.
>
>Du kannst auch sowas
>   namespace unnamed { namespace {
>      void Func() { ... }
>   } }
>   unnamed::Func();
>machen, um die Vorteile des benannten Namespaces (Funktion per
>Namespace-Präfix erreichbar) und des Anonymspaces (Funktion von außen
>nicht erreichbar) zu kombinieren.

Interessante Idee.
Muß ich mal ausprobieren.



>> Ich vermute mal, das es keinen Bedarf dafür gab.
>>
>> BTW, ich habe bisher gerne static für file local scope verwendet, was
>> aber auch nur funktioniert, wenn der Name der Funktion nicht in einem
>> der inkludierten Header vorkommt.
>
>Den Zusammenhang seh ich jetzt nicht. Allerdings ist 'static' meines
>Wissens deprecated und erlaubt auch keine lokalen Klassen-Definitionen.

So hatte ich das auch gedacht. Denn ansonsten hätte man die anonymen
namspaces in C++ ja gar nicht einführen müssen


- Heinz
Re: anonymous namspace referenzieren?
#52492
Author: ram@zedat.fu-ber
Date: Sun, 06 Dec 2015 21:58
36 lines
1581 bytes
Heinz Saathoff <newshsaat@arcor.de> writes:
>Das man einen benannten Namespace definiert und darin wieder static
>nutzt. Eigentlich sollten die anonymous namespaces doch als Ersatz für
>static dienen.

  Vor 2011 hatten die Einträge anonymer Namensräume ja /nicht/
  automatisch interne Bindung. Die anonymen Namensräume
  versteckten lediglich Namen, die normalerweise aber WIMRE noch
  externe Bindung hatten. Die anonymen Namensräume waren also
  ursprünglich vermutlich nicht als Ersatz für »static« gedacht.

>Schöner fände ich allerdings die Nuttzung eines reservierten
>Bezeichners für die anonyme namespace.

  Vielleicht kannst Du ja ähnlich vorgehen, wie WIMRE Boost
  und viele andere Organisationen:

namespace heinz_saathoff  /* Organisationen */
{ namespace wordprocessor /* Projekt        */
  { namespace drawing     /* Modul          */
    { ... }}}

  Nun ist die Wahrscheinlichkeit von Namenskonflikten klein.
  (Falls Du die Organisation einmal verkaufen willst, aber
  besser nicht den eigenen Namen im Quelltext verankern.)
  Die Klienten könnte das dann mit Namespace-Aliassen
  wiede abkürzen.

  Für interne Bindung wollte ich dann allerdings weiterhin
  »static« vorschlagen. Ich kann jetzt nicht erkennen, daß
  das »deprecated« ist. Es war vielleicht einmal in C++03 »deprecated«
  (damals vielleicht: 7.3.1.1/2), aber ist es jetzt wohl nicht mehr.

  Mich stört auch überhaupt nichts an »static«. Es bedeutet ja
  soviel wie »ruhend«, also soll sich der Name nicht aus
  seiner Übersetzungseinheit hinaus bewegen, sondern statisch
  in ihr verharren.
Re: anonymous namspace referenzieren?
#52493
Author: Heinz Saathoff
Date: Mon, 07 Dec 2015 08:54
33 lines
1240 bytes
Christoph Kliemt schrieb:

>ram@zedat.fu-berlin.de (Stefan Ram) writes:
>
>> Heinz Saathoff <newshsaat@arcor.de> writes:
>>>Daniel Krügler schrieb:
>>>>a) Deklarieren einen benannten Namensraum und
>>>>b) Deklariere seinen Inhalt so, dass er interne Bindung hat
>>>Ich muß sagen, dass mir diese Lösung nicht besonders gefällt.
>>
>>   Und was gefällt Dir daran nicht?
>
>In meiner schlichten Naivität frage ich mich: Wofür braucht man sowas?

Ich bin zufällig auf ein Problem mit einer Namensgleichheit gestoßen.
Beim Portieren einer Anwendung mussten zusätzlich Header inkludiert
werden, un in einem der Header war der gleiche Name vorhanden, den ich
auch für mich genutzt hatte. Da kam einfach die Idee auf, einen
anonymen Namensraum darum herum zu setzen. Und das geht auch, solange
der Aufrufer auch in dem Namensaum ist. Nur nicht, wenn die anonyme
Funktion von ausserhalb des Namensraumes gerufen wird, weil dann ein
Kollision mit dem per Fremdheader inkludierten Namen existiert.
Allerdings hilft das alles nichts, wenn der Name im Header ein #define
ist, da Textersatz sich nicht um Namensräume kümmert.

Gelöst habe ich das letztendlich doch per Umbennung.


>Gruss Christoph
>
>p.s. Die Frage ist durchaus ernstgemeint!


- Heinz
Re: anonymous namspace referenzieren?
#52494
Author: Heinz Saathoff
Date: Mon, 07 Dec 2015 08:55
21 lines
932 bytes
Stefan Ram schrieb:

>Heinz Saathoff <newshsaat@arcor.de> writes:
>>Das man einen benannten Namespace definiert und darin wieder static
>>nutzt. Eigentlich sollten die anonymous namespaces doch als Ersatz für
>>static dienen.
>
>  Vor 2011 hatten die Einträge anonymer Namensräume ja /nicht/
>  automatisch interne Bindung. Die anonymen Namensräume
>  versteckten lediglich Namen, die normalerweise aber WIMRE noch
>  externe Bindung hatten. Die anonymen Namensräume waren also
>  ursprünglich vermutlich nicht als Ersatz für »static« gedacht.

Wobei ich nicht verstehe, warum diese externe Bindung haben sollen,
wenn sie aus einer anderen Übersetzungseinheit sowieso nicht
referenziert werden können. Die Namen mögen zwar im Objektfile landen,
aber das ist nur ein Implementierungsdetail. Eigentlich konnte ein
Compiler auch bei C++98 eine innterne Bindung definieren. Ich wüsste
nicht, wo da ein Unterschied sein sollte.


- Heinz
Re: anonymous namspace referenzieren?
#52496
Author: Stefan Reuther
Date: Mon, 07 Dec 2015 19:13
31 lines
1521 bytes
Am 07.12.2015 um 08:55 schrieb Heinz Saathoff:
> Stefan Ram schrieb:
>> Heinz Saathoff <newshsaat@arcor.de> writes:
>>> Das man einen benannten Namespace definiert und darin wieder static
>>> nutzt. Eigentlich sollten die anonymous namespaces doch als Ersatz für
>>> static dienen.
>>
>>  Vor 2011 hatten die Einträge anonymer Namensräume ja /nicht/
>>  automatisch interne Bindung. Die anonymen Namensräume
>>  versteckten lediglich Namen, die normalerweise aber WIMRE noch
>>  externe Bindung hatten. Die anonymen Namensräume waren also
>>  ursprünglich vermutlich nicht als Ersatz für »static« gedacht.
>
> Wobei ich nicht verstehe, warum diese externe Bindung haben sollen,
> wenn sie aus einer anderen Übersetzungseinheit sowieso nicht
> referenziert werden können. Die Namen mögen zwar im Objektfile landen,
> aber das ist nur ein Implementierungsdetail. Eigentlich konnte ein
> Compiler auch bei C++98 eine innterne Bindung definieren. Ich wüsste
> nicht, wo da ein Unterschied sein sollte.

Die Dinger haben formal externe Bindung, weil das in C++98 notwendig
ist, um sie mit Templates verwenden zu können.

Natürlich kann auch ein C++98-Compiler die Symbole auch einfach mit
interner Bindung anlegen. Dazu hätte er zwischen der Bindung, die er in
die Objektdateien schreibt, und der, die das Ding laut Sprachstandard
hat, unterscheiden müssen. Das macht die Sache halt nicht einfacher, und
die damaligen Compiler hatten schon so genug zu tun, überhaupt erstmal
den Featureumfang von C++ umzusetzen...


  Stefan
Thread Navigation

This is a paginated view of messages in the thread with full content displayed inline.

Messages are displayed in chronological order, with the original post highlighted in green.

Use pagination controls to navigate through all messages in large threads.

Back to All Threads